gc — 가비지 컬렉터 인터페이스
gc — 가비지 컬렉터 인터페이스
이 모듈은 선택적 가비지 컬렉터에 대한 인터페이스를 제공해요. 컬렉터를 비활성화하고, 수집 빈도를 조정하고, 디버깅 옵션을 설정하는 기능을 제공해요. 또한 컬렉터가 찾았지만 해제할 수 없는 도달 불가능한 객체에 접근할 수도 있어요. 컬렉터는 Python에 이미 있는 참조 카운팅을 보완하므로, 프로그램이 참조 순환(reference cycle)을 만들지 않는다고 확신하면 컬렉터를 비활성화할 수 있어요. 자동 수집은 gc.disable()로 끌 수 있어요. 누수 프로그램을 디버깅하려면 gc.set_debug(gc.DEBUG_LEAK)를 호출하면 되는데, 여기엔 gc.DEBUG_SAVEALL이 포함되어 가비지 컬렉션된 객체가 검사용으로 gc.garbage에 저장되므로 참고하세요.
출처: Python 표준 라이브러리
본문
gc 모듈은 다음 함수들을 제공해요.
gc.enable()
자동 가비지 컬렉션을 활성화해요.
gc.disable()
자동 가비지 컬렉션을 비활성화해요.
gc.isenabled()
자동 컬렉션이 활성화돼 있으면 True를 돌려줘요.
gc.collect(generation=2)
인자 없이 호출하면 전체 컬렉션을 실행해요. 선택 인자 generation은 수집할 세대(0부터 2까지)를 지정하는 정수일 수 있어요. 세대 번호가 유효하지 않으면 ValueError가 발생해요. 수집된 객체 수와 수집 불가능한 객체 수의 합을 돌려줘요.
여러 내장 타입에 대해 유지되는 프리 리스트(free list)는 전체 컬렉션 또는 최고 세대(2) 컬렉션이 실행될 때마다 비워져요. 일부 프리 리스트의 모든 항목은 특정 구현 때문에, 특히 float는 해제되지 않을 수 있어요.
인터프리터가 이미 컬렉션을 수행하는 중에 gc.collect()를 호출하는 효과는 정의되지 않아요.
버전 3.14에서 변경: generation=1이 컬렉션 증가분을 수행함.
버전 3.14.5에서 변경: generation=1이 중간 세대를 수집함.
gc.set_debug(flags)
가비지 컬렉션 디버깅 플래그를 설정해요. 디버깅 정보는 sys.stderr에 쓰여요. 아래에서 컬렉션 디버깅을 제어하기 위해 비트 연산으로 결합할 수 있는 디버깅 플래그 목록을 볼게요.
gc.get_debug()
현재 설정된 디버깅 플래그를 돌려줘요.
gc.get_objects(generation=None)
컬렉터가 추적하는 모든 객체의 리스트를 돌려줘요(반환되는 리스트 자체는 제외). generation이 None이 아니면 해당 세대에 있는 컬렉터 추적 객체만 돌려줘요.
버전 3.8에서 변경: 새 generation 매개변수.
버전 3.14에서 변경: 세대 1이 제거됨.
버전 3.14.5에서 변경: 세대 1이 3.13과 동일한 GC 동작을 유지하도록 다시 도입됨.
인자 generation과 함께 감사 이벤트 gc.get_objects를 발생시켜요.
gc.get_stats()
인터프리터 시작 이후의 수집 통계를 담은 세대별 딕셔너리 3개의 리스트를 돌려줘요. 키 수는 미래에 바뀔 수 있지만, 현재 각 딕셔너리는 다음 항목을 담아요.
collections— 이 세대가 수집된 횟수.collected— 이 세대 안에서 수집된 총 객체 수.uncollectable— 이 세대 안에서 수집 불가능한 것으로 발견된(그래서 가비지 리스트로 옮겨진) 총 객체 수.
버전 3.4에 추가됨.
gc.set_threshold(threshold0[, threshold1[, threshold2]])
가비지 컬렉션 임계값(수집 빈도)을 설정해요. threshold0을 0으로 설정하면 컬렉션이 비활성화돼요.
GC는 객체가 몇 번의 수집 스윕을 견뎠는지에 따라 객체를 세 가지 세대(0, 1, 2)로 분류해요. 새 객체는 최연소 세대(세대 0)에 놓이고, 객체가 수집을 견디면 다음으로 오래된 세대(1)로 옮겨져요. 세대 2는 최고령 세대라 그 세대의 객체는 수집 후에도 그대로 남아요. 컬렉터는 언제 실행할지 결정하기 위해 마지막 컬렉션 이후의 객체 할당·해제 수를 추적해요. 할당 수에서 해제 수를 뺀 값이 threshold0을 초과하면 수집이 시작돼요. 처음에는 세대 0만 검사해요. 세대 0이 세대 1이 검사된 이후로 threshold1을 초과한 횟수만큼 검사됐다면 세대 1도 검사해요. 세 번째 세대는 조금 더 복잡한데, 최고령 세대 수집에 대한 자세한 내용을 참고하세요.
프리-스레드 빌드에서는 컬렉터를 실행하기 전에 프로세스 메모리 사용량 증가도 확인해요. 메모리 사용량이 마지막 수집 이후 10% 증가하지 않았고 객체 할당 순 수가 threshold0의 40배를 초과하지 않았다면 컬렉션이 실행되지 않아요.
버전 3.14에서 변경: threshold2가 무시됨.
버전 3.14.5에서 변경: threshold2가 Python 3.13 동작을 따르도록 복원됨.
gc.get_count()
현재 수집 횟수를 (count0, count1, count2) 튜플로 돌려줘요.
gc.get_threshold()
현재 수집 임계값을 (threshold0, threshold1, threshold2) 튜플로 돌려줘요.
gc.get_referrers(*objs)
objs 중 어느 하나를 직접 참조하는 객체의 리스트를 돌려줘요. 이 함수는 가비지 컬렉션을 지원하는 컨테이너만 찾아요. 다른 객체를 참조하지만 가비지 컬렉션을 지원하지 않는 확장 타입은 찾지 못해요.
이미 역참조됐지만 순환 속에 살아 아직 가비지 컬렉터가 수집하지 않은 객체도 결과 referrer에 나열될 수 있다는 점을 기억하세요. 현재 살아있는 객체만 얻으려면 get_referrers()를 호출하기 전에 collect()를 호출하면 돼요.
경고 —
get_referrers()가 반환한 객체를 쓸 때는 주의해야 해요. 그중 일부는 아직 구성 중이라 일시적으로 유효하지 않은 상태일 수 있으니까요.get_referrers()를 디버깅 외의 목적으로 쓰는 것은 피하세요.
인자 objs와 함께 감사 이벤트 gc.get_referrers를 발생시켜요.
gc.get_referents(*objs)
인자 중 어느 하나가 직접 참조하는 객체의 리스트를 돌려줘요. 반환되는 referent는 인자의 C 레벨 tp_traverse 메서드(있으면)가 방문한 객체들로, 실제로 직접 도달 가능한 모든 객체가 아닐 수 있어요. tp_traverse 메서드는 가비지 컬렉션을 지원하는 객체만 지원하고, 순환에 관여할 수 있는 객체만 방문하면 돼요. 그래서 예를 들어 정수가 인자에서 직접 도달 가능하다면 그 정수 객체는 결과 리스트에 나타날 수도 있고 아닐 수도 있어요.
인자 objs와 함께 감사 이벤트 gc.get_referents를 발생시켜요.
gc.is_tracked(obj)
객체가 현재 가비지 컬렉터에 추적되고 있으면 True, 아니면 False를 돌려줘요. 일반적으로 원자 타입의 인스턴스는 추적되지 않고, 비원자 타입(컨테이너, 사용자 정의 객체 등)의 인스턴스는 추적돼요. 다만 단순 인스턴스의 GC 발자국을 줄이기 위해 타입별 최적화가 있을 수 있어요(예: 원자 키·값만 담는 dict).
>>> gc.is_tracked(0)
False
>>> gc.is_tracked("a")
False
>>> gc.is_tracked([])
True
>>> gc.is_tracked({})
False
>>> gc.is_tracked({"a": 1})
True
버전 3.1에 추가됨.
gc.is_finalized(obj)
주어진 객체가 가비지 컬렉터에 의해 파이널라이즈됐으면 True, 아니면 False를 돌려줘요.
>>> x = None
>>> class Lazarus:
... def __del__(self):
... global x
... x = self
...
>>> lazarus = Lazarus()
>>> gc.is_finalized(lazarus)
False
>>> del lazarus
>>> gc.is_finalized(x)
True
버전 3.9에 추가됨.
gc.freeze()
가비지 컬렉터가 추적하는 모든 객체를 동결해요. 영구 세대(permanent generation)로 옮기고 이후 모든 컬렉션에서 무시해요.
프로세스가 exec() 없이 fork()할 것이라면, 자식 프로세스의 불필요한 copy-on-write를 피하면 메모리 공유를 최대화하고 전체 메모리 사용량을 줄일 수 있어요. 그러려면 부모 프로세스에서 해제된 "구멍"을 메모리 페이지에 만들지 않는 것과, 자식 프로세스의 GC 컬렉션이 부모 프로세스에서 온 장수 객체의 gc_refs 카운터를 건드리지 않는 것, 두 가지가 필요해요. 둘 다 달성하려면 부모 프로세스에서 일찍 gc.disable()을 호출하고, fork() 직전에 gc.freeze()를, 자식 프로세스에서 일찍 gc.enable()을 호출하면 돼요.
버전 3.7에 추가됨.
gc.unfreeze()
영구 세대의 객체를 풀어서 최고령 세대로 되돌려놓아요.
버전 3.7에 추가됨.
gc.get_freeze_count()
영구 세대의 객체 수를 돌려줘요.
버전 3.7에 추가됨.
다음 변수들은 읽기 전용 접근용으로 제공돼요(값은 바꿀 수 있지만 재바인딩하면 안 돼요).
gc.garbage
컬렉터가 도달 불가능하지만 해제할 수 없는(수집 불가능한) 객체들의 리스트예요. Python 3.4부터 이 리스트는 대부분 비어 있어야 해요. 단, 비-NULL tp_del 슬롯을 가진 C 확장 타입 인스턴스를 쓸 때는 예외예요.
DEBUG_SAVEALL이 설정돼 있으면 해제하는 대신 모든 도달 불가능한 객체가 이 리스트에 추가돼요.
버전 3.2에서 변경: 인터프리터 종료 시 이 리스트가 비어 있지 않으면 기본적으로 조용한 ResourceWarning이 발생함. DEBUG_UNCOLLECTABLE이 설정돼 있으면 모든 수집 불가능 객체도 함께 출력됨.
버전 3.4에서 변경: PEP 442에 따라 __del__() 메서드를 가진 객체는 더 이상 gc.garbage에 들어가지 않음.
gc.callbacks
가비지 컬렉터가 수집 전후에 호출할 콜백의 리스트예요. 콜백은 phase와 info 두 인자로 호출돼요.
phase는 두 값 중 하나일 수 있어요.
"start"— 가비지 컬렉션이 시작하려 함."stop"— 가비지 컬렉션이 끝났음.
info는 콜백에 더 많은 정보를 주는 dict예요. 현재 정의된 키는 다음과 같아요.
"generation"— 수집 중인 최고령 세대."collected"—phase가"stop"일 때, 성공적으로 수집된 객체 수."uncollectable"—phase가"stop"일 때, 수집할 수 없어garbage에 넣은 객체 수.
애플리케이션은 이 리스트에 자신의 콜백을 추가할 수 있어요. 주요 사용 사례는 다음과 같아요.
- 가비지 컬렉션에 대한 통계 수집(각 세대가 얼마나 자주, 얼마나 오래 수집되는지).
garbage에 자신의 수집 불가능 타입이 나타났을 때 식별하고 지우기.
버전 3.3에 추가됨.
set_debug()와 함께 사용할 다음 상수들이 제공돼요.
gc.DEBUG_STATS— 수집 중 통계를 출력해요. 수집 빈도를 조정할 때 유용할 수 있어요.gc.DEBUG_COLLECTABLE— 발견된 수집 가능한 객체에 대한 정보를 출력해요.gc.DEBUG_UNCOLLECTABLE— 발견된 수집 불가능한 객체(도달 불가능하지만 컬렉터가 해제할 수 없는 객체)에 대한 정보를 출력해요. 이 객체들은 가비지 리스트에 추가돼요. (버전 3.2에서 변경: 종료 시 가비지 리스트가 비어 있지 않으면 그 내용도 출력함.)gc.DEBUG_SAVEALL— 설정하면 발견된 모든 도달 불가능한 객체를 해제하는 대신garbage에 추가해요. 누수 프로그램 디버깅에 유용할 수 있어요.gc.DEBUG_LEAK— 컬렉터가 누수 프로그램에 대한 정보를 출력하는 데 필요한 디버깅 플래그(DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE | DEBUG_SAVEALL과 같음).