Python Academy · 강의

가비지 수집기와 순환 참조

gc 모듈이 참조 순환을 처리하는 방식을 학습합니다.

레슨 2/413개 단계

가비지 수집기와 순환 참조은(는) CoddyKit의 무료 Python Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Python Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Python Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

참조 횟수 관리만으로는 충분하지 않은 이유

참조 횟수 관리만으로는 참조 순환에 포함된 객체를 수집할 수 없습니다. 각 객체가 다른 객체에 대한 참조를 보유하므로 어느 쪽의 횟수도 0으로 떨어지지 않기 때문입니다.

# Reference cycle: a → b → a
a = {}
b = {"other": a}
a["other"] = b
del a, b
# Both objects are unreachable but refcount > 0
# Only the cyclic GC can collect them

gc 모듈

gc는 순환 가비지 컬렉터입니다. 추적 중인 객체에서 도달할 수 없는 순환을 주기적으로 검사하고 수집합니다.

import gc

gc.collect()   # trigger immediately
print(gc.garbage)   # objects with __del__ in cycles (cannot auto-collect)

세대별 수집

GC는 세 개의 세대를 사용합니다. 새 객체는 0세대에서 시작합니다. 수집 후에도 살아남은 객체는 상위 세대로 승격됩니다. 0세대가 가장 자주 수집됩니다.

import gc

print(gc.get_count())     # (gen0, gen1, gen2) allocations since last collection
print(gc.get_threshold()) # (700, 10, 10) — thresholds for each generation
gc.set_threshold(1000, 15, 10)  # tune

gc.get_referents로 순환 감지

객체가 참조하는 객체를 검사합니다. 무언가가 수집되지 않는 이유를 이해할 때 유용합니다.

import gc

a = []
b = [a]
a.append(b)

for ref in gc.get_referents(a):
    print(ref)   # shows b

gc.get_objects()

gc.get_objects()는 현재 GC가 추적하는 모든 객체를 반환합니다. 메모리 누수를 찾을 때 유용합니다.

import gc

before = len(gc.get_objects())
create_lots_of_objects()
after = len(gc.get_objects())
print(f"Leaked: {after - before} objects")

순환 방지

순환을 피하도록 데이터 구조를 설계하십시오. 역방향 참조에는 weakref를 사용하고, 직접 참조 대신 ID를 사용하거나, 객체가 범위를 벗어나기 전에 순환을 명시적으로 끊습니다.

import weakref

class Node:
    def __init__(self, parent):
        # weakref avoids cycle:
        self.parent = weakref.ref(parent)

class Tree:
    def __init__(self):
        self.child = Node(self)   # no hard cycle

__del__과 순환

순환 구조에 포함된 __del__이 있는 객체는 자동으로 수집할 수 없습니다. 대신 gc.garbage에 배치됩니다.

import gc

class Leaky:
    def __del__(self): pass

a = Leaky()
b = Leaky()
a.other = b
b.other = a
del a, b

gc.collect()
print(gc.garbage)   # [Leaky, Leaky] — cannot collect

gc.freeze() — Python 3.7+

gc.freeze()는 현재 추적 중인 객체를 고정하여 절대 수집되지 않도록 합니다. 시작이 완료된 후 장시간 실행되는 프로세스에서 GC 일시 중지를 줄이는 데 유용합니다.

import gc

# After all globals and imports are in place:
gc.freeze()   # no GC scanning for these objects ever again

# Useful for: gunicorn pre-fork, background servers

GC 비활성화 및 다시 활성화

순환이 없다는 것을 알고 있는 매우 빈번한 루프에서는 순환 GC를 비활성화한 다음, 이후 다시 활성화하고 수집을 강제로 실행합니다.

import gc

gc.disable()
try:
    result = tight_loop_no_cycles()
finally:
    gc.enable()
    gc.collect()

isenabled 및 isfinalized

gc.isenabled()로 GC 상태를 확인하고 gc.is_finalized(obj)로 객체가 종료 처리되었는지 감지합니다.

import gc

print(gc.isenabled())      # True by default
obj = object()
print(gc.is_finalized(obj))  # False (still alive)

메모리 누수 패턴

Python에서 메모리 누수를 일으키는 일반적인 원인은 제한 없이 증가하는 전역 캐시, 분리되지 않은 이벤트 수신기, __del__이 포함된 참조 순환과 C 확장 기능의 참조 누수입니다.

# Typical leaks:
global_cache = {}   # grows forever — use lru_cache with maxsize

class EventBus:
    listeners = []
    # Listeners hold references to objects:
    # @classmethod
    # def on(cls, fn): cls.listeners.append(fn)
    # Must call off() to detach

빠른 확인

참조 순환에 포함된 __del__이 있는 객체에는 어떤 일이 발생합니까?

복습

순환 GC는 참조 횟수 관리로 처리할 수 없는 참조 순환을 처리합니다. 세 개의 세대를 사용하고 살아남은 객체를 승격합니다. weakref로 순환을 피하십시오. 순환 구조의 __del__이 있는 객체는 gc.garbage에 들어갑니다. 장시간 실행되는 서버에서는 시작 후 gc.freeze()를 사용하여 GC 일시 중지를 줄이십시오.

무료로 시작

AI 튜터와 함께 Python을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
76
레슨
320

자주 묻는 질문

“가비지 수집기와 순환 참조” 강의는 무료인가요?

네 — “가비지 수집기와 순환 참조” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Python Academy 강의 전체를 잠금 해제할 수 있습니다. Python Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“가비지 수집기와 순환 참조”에서 뭘 배우나요?

gc 모듈이 참조 순환을 처리하는 방식을 학습합니다. 브라우저에서 직접 실행하는 실습 코드로 Python Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Python Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Python Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“가비지 수집기와 순환 참조” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Python Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Python Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. CPython 참조 횟수 계산
  2. 가비지 수집기와 순환 참조
  3. cProfile과 line_profiler로 프로파일링
  4. tracemalloc으로 메모리 프로파일링
← Python Academy(으)로 돌아가기