참조 카운팅 (Reference Counting)
참조 카운팅은 객체가 몇 개의 다른 객체나 변수가 자신을 참조하고 있는지를 세는 방식.
객체가 참조될 때마다 카운트 증가, 참조가 해제되면 카운트 감소. 참조 카운트가 '0'이 되면
더 이상 그 객체를 참조하는 곳이 없으므로 가비지 컬렉션의 대상이 됩니다.
class Node:
def __init__(self, value):
self.value = value
self.ref = None # 다른 노드를 가리키는 참조
node1 = Node(1)
node2 = Node(2)
# 현재 상태:
# node1 참조 카운트: 1 (node1 변수)
# node2 참조 카운트: 1 (node2 변수)
node1.ref = node2
node2.ref = node1
# 현재 상태:
# node1 참조 카운트: 1 (node1 변수)
# node2 참조 카운트: 2 (node2 변수와 node1의 ref)
위 코드에서 node1과 node2는 서로를 참조합니다. 만약 이 두 노드를 더 이상 다른 변수나 객체에서 참조하지 않게 되어도, 이들이 서로를 참조하고 있는 한, 참조 카운트는 0이 되지 않습니다. 그래서 이 두 객체는 가비지 컬렉션 대상이 되지 않습니다. 이게 바로 순환 참조(Circular Reference) 문제입니다.
2. 순환 참조 (Circular Reference)
순환 참조는 두 개 이상의 객체가 서로를 참조하면서 생기는 상황입니다. 예를 들어 node1이 node2를 참조하고, node2가 다시 node1을 참조하는 상황입니다. 이때, 두 객체는 다른 곳에서 더 이상 참조되지 않더라도 서로를 참조하고 있기 때문에, 참조 카운트가 0이 되지 않습니다. 따라서 참조 카운팅 방식만으로는 이 객체들을 가비지 컬렉션할 수 없게 됩니다.
node1 = Node(1)
node2 = Node(2)
node1.ref = node2
node2.ref = node1
# 이제 node1과 node2는 서로를 참조하는 순환 참조 상태입니다.
node1 = None
node2 = None
# 현재 상태:
# node1과 node2는 None이 되었으므로, 다른 변수에서는 이 객체들을 더 이상 참조하지 않음
# 그러나 node1과 node2가 서로를 참조하고 있어서, 이들은 여전히 메모리에 남아 있음
위 상황에서는 node1과 node2가 서로를 참조하고 있으므로 참조 카운트가 0이 되지 않습니다. 따라서, 이 객체들은 메모리에서 해제되지 않고 메모리 누수를 일으킬 수 있습니다.
3. 순환 검출 (Cycle Detection)
순환 검출은 이러한 순환 참조 문제를 해결하기 위한 가비지 컬렉션의 추가적인 단계입니다. 참조 카운팅만으로는 순환 참조를 해결할 수 없기 때문에, 파이썬과 같은 언어에서는 주기적으로 힙 메모리를 스캔하여 순환 참조를 찾아내고, 그 객체들을 가비지 컬렉션할 수 있는 순환 검출 알고리즘을 사용합니다.
import gc # 가비지 컬렉션 모듈
gc.collect() # 수동으로 가비지 컬렉션을 트리거하여 순환 참조된 객체를 제거
위 코드는 파이썬에서 가비지 컬렉션을 수동으로 트리거하여 순환 참조로 인한 메모리 누수를 방지할 수 있습니다. 파이썬의 가비지 컬렉터는 이러한 순환 참조를 감지하고, 참조 카운트가 0이 될 수 없는 경우에도 객체를 안전하게 메모리에서 해제할 수 있습니다.
4. 요약
- 참조 카운팅: 객체가 몇 개의 다른 객체나 변수가 자신을 참조하는지를 세어, 참조 카운트가 0이 되면 가비지 컬렉션을 통해 메모리에서 해제됩니다.
- 순환 참조: 두 개 이상의 객체가 서로를 참조하여, 참조 카운트가 0이 되지 않아 가비지 컬렉션이 되지 않는 상황입니다.
- 순환 검출: 가비지 컬렉션의 일환으로 순환 참조를 감지하고, 이를 해결하여 메모리 누수를 방지하는 방법입니다.
이와 같이 참조 카운팅은 기본적인 가비지 컬렉션 방법이고, 순환 검출은 참조 카운팅만으로 해결되지 않는 순환 참조 문제를 처리하기 위한 추가적인 단계입니다.
'BE,FE(개발) > Java,Python (server)' 카테고리의 다른 글
| 오랜만에 정리하는 자바의 인스턴스와 String Pool (0) | 2024.08.16 |
|---|---|
| 이제 와서 정리해보는 파이썬과 자바의 GC(garbage Collector) (0) | 2024.08.16 |
| 파이썬에서 SQL 쿼리 관리: .py 파일 vs YAML 파일 (0) | 2024.07.30 |
| Minimal APIs vs. Controllers: 무엇이 더 나을까요? (0) | 2024.07.29 |
| 면접 공부를 하다 DI를 공부하다.(Spring) (0) | 2023.01.14 |