참조 카운팅 (reference counting)
쉽게 풀면
참조 카운팅은 각 객체에 '지금 나를 가리키고 있는 곳이 몇 군데인가'를 세는 숫자표를 붙여두는 방식이다. 새로운 곳에서 그 객체를 참조하기 시작하면 숫자를 하나 늘리고, 참조가 끊기면 숫자를 하나 줄인다. 이 숫자가 0이 되는 순간, 아무도 그 객체를 쓰지 않는다는 뜻이므로 즉시 메모리를 회수할 수 있다. 마크-앤-스윕 방식처럼 프로그램을 잠시 멈추고 전체를 훑을 필요가 없어 회수 시점이 예측 가능하다는 장점이 있지만, 두 객체가 서로를 참조하는 순환 참조가 생기면 둘 다 카운트가 0이 되지 않아 메모리가 회수되지 못하는 문제가 발생할 수 있다.
왜 중요한가
참조 카운팅은 메모리를 자동으로 관리하면서도 회수 시점을 비교적 예측 가능하게 만드는 방식이기 때문에, 프로그래밍 언어 설계와 런타임 시스템 연구에서 마크-앤-스윕 같은 다른 가비지 컬렉션 기법과 나란히 비교되는 핵심 주제입니다. 특히 응답 지연을 최소화해야 하는 실시간 시스템이나 모바일 환경에서는 메모리 회수가 예측 가능하다는 점이 성능 설계에 중요한 요소로 작용해 관련 연구가 꾸준히 이루어집니다.
논문에서는 이렇게 쓰입니다
가비지 컬렉션의 한 방식으로서 참조 카운팅의 동작 원리와 한계를 설명할 때 사용된다.
모바일·임베디드 시스템 연구에서는 응답성이 중요한 환경에서 참조 카운팅이 가진 예측 가능한 회수 시점이라는 장점이 자주 강조됩니다.
병렬·동시성 프로그래밍 연구에서는 여러 스레드가 동시에 참조 카운트를 증가·감소시킬 때 발생할 수 있는 오류를 막기 위한 구현 기법이 다뤄지기도 합니다.
조금 더 깊게 보면
참조 카운팅의 가장 큰 실무적 한계는 순환 참조인데, 이를 보완하기 위해 실제 언어 구현체들은 흔히 강한 참조(strong reference)와 약한 참조(weak reference)를 구분해 둡니다. 강한 참조는 카운트를 증가시키지만 약한 참조는 카운트에 영향을 주지 않아, 상호 참조하는 객체 중 한쪽을 약한 참조로 지정하면 순환 고리를 끊어 정상적으로 회수될 수 있습니다. 일부 언어는 여기에 더해 주기적으로 순환 구조를 탐지해 강제로 회수하는 별도의 순환 탐지기(cycle collector)를 참조 카운팅과 함께 운용하기도 합니다.
주의할 점
참조 카운팅만으로는 서로를 순환적으로 참조하는 객체들의 메모리를 회수할 수 없으므로, 이를 해결하기 위해 별도의 순환 탐지기나 약한 참조 개념을 함께 도입하는 경우가 많다.