Reference Counting

객체를 참조하는 횟수를 카운팅하여 카운트가 0이 되면 메모리를 해제하는 GC 방식입니다.

동작 방식

객체 생성      → count = 1
참조 추가      → count++
참조 해제      → count--
count == 0   → 메모리 해제 O

예시

# Python은 Reference Counting 방식 사용
a = [1, 2, 3]  # count = 1
b = a          # count = 2
a = None       # count = 1
b = None       # count = 0 → 메모리 해제 O

순환 참조 문제

A → B → A (서로 참조)

A.count = 1 (B가 참조)
B.count = 1 (A가 참조)

외부에서 A, B 참조 해제해도
→ 서로 참조하므로 count가 0이 되지 않음
→ 메모리 해제 불가
# 순환 참조 예시
class Node:
    def __init__(self):
        self.ref = None

a = Node()
b = Node()
a.ref = b  # a → b
b.ref = a  # b → a (순환 참조)

a = None
b = None
# count가 0이 안 되어 메모리 누수 발생

순환 참조 해결

Python: 주기적으로 순환 참조 탐지하는 보조 GC 사용
Java: Reference Counting 대신 Reachability 방식 사용
     → 순환 참조해도 GC Root에서 도달 불가면 수거 O

Reachability와 비교

Reference CountingReachability
해제 시점즉시 (count = 0)GC 실행 시
순환 참조해결 불가해결 가능 O
STW없음발생
오버헤드count 관리 비용탐색 비용
사용 언어Python, SwiftJava, C#

Reference Counting은 즉시 메모리 해제가 가능하다는 장점이 있지만, 순환 참조 문제로 인해 Java는 Reachability 방식을 채택했습니다.

CSLOG에서 보기