파이썬은 가비지를 어떻게 처리할까?
Python은 불필요한 객체(가비지)를 정리하기 위해 두 가지 기법을 사용합니다.
첫 번째는 참조 카운팅(reference counting)입니다. 이 방식은 모든 객체에 적용되지만, 서로 직접 혹은 간접적으로 참조하는 객체들, 즉 순환 참조(circular reference)는 해제하지 못하는 근본적인 한계가 있습니다.
바로 이 지점에서 실질적인 가비지 컬렉터가 역할을 합니다. 파이썬에는 gc 모듈이 내장되어 있으며, 이 모듈은 자신이 추적하고 있는 객체들을 대상으로 순환 참조를 탐색해 제거합니다.
순환 참조 GC의 추적 대상
그러나 모든 객체가 순환 참조 검사에 참여하는 것은 아닙니다. 잠재적으로 순환 참조에 포함될 가능성이 있는 객체만이 순환 GC의 대상이 됩니다. 예를 들어 리스트(list)는 해당되지만, 문자열(string)은 다른 객체를 전혀 참조하지 않으므로 추적 대상에서 제외됩니다.
파이썬에서 정의된 모든 클래스와 그 인스턴스는 자동으로 순환 GC의 추적을 받습니다. 반면 C 언어로 구현된 타입은 개발자가 별도로 추적 기능을 구현하지 않는 한 GC의 관리 대상이 아닙니다. 물론 순환에 포함될 가능성이 있는 내장 타입들은 대부분 추적 대상에 포함되어 있습니다. 결국 gc 모듈은 '규칙에 따라 협조하는' 타입들만 알고 있다는 의미입니다.
obmalloc: 파이썬 고유의 메모리 할당자
수거 메커니즘 외에도 알아두면 좋은 사실이 있습니다. 파이썬은 자체적인 집계형 메모리 할당자인 obmalloc을 사용합니다. 이 할당자는 메모리 아레나(arena)라는 큰 덩어리 단위로 메모리를 확보하고, 생성되는 대부분의 작은 객체에 이 공간을 재활용합니다.
파이썬은 요즘 아레나가 완전히 비었을 때 이를 시스템에 반환합니다(과거에는 오랫동안 반환하지 않았습니다). 하지만 실제로 아레나를 완전히 비우는 일은 매우 드뭅니다. 파이썬 객체는 이동 불가능(non-movable)하기 때문에, 남겨진 소수의 객체를 다른 아레나로 옮겨 공간을 정리할 수 없기 때문입니다.