tracemalloc — 메모리 할당 추적
tracemalloc — 메모리 할당 추적
tracemalloc 모듈은 파이썬 프로그램이 할당한 메모리 블록을 추적하는 디버깅 도구예요. 다음 정보를 제공해요.
- 추적 여부: 할당된 파이썬 객체의 객체가 할당된 위치의 역추적(backtrace).
- 통계: 코드별·모듈별로 얼마나 많은 메모리가 할당되어 사용됐는지 비교할 수 있는 할당 블록 수·크기 통계.
트레이스는 할당이 발생한 코드와 릴리즈(해제)되지 않은 후에도 대부분의 사용 사례에서 할당이 발생한 위치를 정확히 밝혀줍니다. 프로세스 간 메모리 블록을 비교하려면 이 모듈보다 sys.getsizeof()·resource가 더 적합할 수 있어요.
기본적으로 추적이 비활성화돼 있어, tracemalloc.start() 등으로 활성화해 사용합니다. PYTHONTRACEMALLOC 환경 변수로 시작 시 활성화할 수도 있어요.
본문
시작하기 (Enable/Disable)
tracemalloc.start(nframe=1) — 파이썬 메모리 할당 추적을 시작해요. 이미 시작되어 있으면 RuntimeError가 발생합니다. 기본적으로 스택의 가장 안쪽 프레임(nframe=1)만 추적합니다. 트레이스버퍼가 nframe만큼의 프레임 수로 늘어나므로, 백트레이스를 얻으려면 nframe을 증가시켜야 해요. 추적된 트레이스백을 정확히 다시 얻으려면 첫 번째 프레임이 중요합니다. (왜냐하면 추적은 호출 시점의 할당만을 기록하기 때문이에요.) 한 번이라도 객체를 해제하지 않아도 백트레이스를 유지하려면 스택 프레임을 더 추적해야 합니다.
tracemalloc.stop() — 메모리 할당 추적을 멈추고, get_traced_memory()가 추적 상태를 리셋해 줘요. 추적이 시작되어 있지 않으면 RuntimeError가 발생합니다.
tracemalloc.is_tracing() — 메모리 할당 추적이 활성화되어 있으면 True를 반환해요.
tracemalloc.get_traceback_limit() / tracemalloc.set_traceback_limit(nframe) — 추적된 스택 프레임 수의 한계를 가져오거나 설정해요. 백트레이스가 기억된 프레임 수는 max(traceback_limit, nframe)입니다.
계산 (Counting)
tracemalloc.get_traced_memory() — (current, peak) 튜플로 현재와 최대 메모리 블록 크기(바이트)를 반환해요. 추적 상태에 따라 결과가 달라집니다. current는 현재 할당된 메모리, peak는 추적 시작 이후 최대 크기예요.
tracemalloc.reset_peak() — (추적된 메모리의) 최댓값을 리셋해요. / 버전 3.9에서 추가.
tracemalloc.get_object_traceback(obj) — 파이썬 객체가 추적된 메모리 블록이면 그 객체의 할당 위치의 트레이스백을 반환하고, 확인되지 않으면 None을 반환해요.
Snapshot (스냅샷)
tracemalloc.take_snapshot() — 메모리 할당 블록의 스냅샷을 찍어 Snapshot 인스턴스를 반환해요. 추적 상태에 따라 결과가 달라집니다.
class tracemalloc.Snapshot — 메모리 할당 블록의 스냅샷. 그룹화하거나, 다른 스냅샷과 비교할 수 있어요.
snapshot.dump(filename) — 스냅샷을 파일에 저장해요. pickle로 Snapshot을 저장합니다. (추적 중인 블록이 있어도 파일이 반드시 성공적으로 생성되도록, f.flush()가 호출됩니다.)
snapshot.load(filename) — dump()로 만든 파일에서 스냅샷을 불러와요.
snapshot.statistics(key_type, cumulative=False) — Statistic 객체(할당 블록 수·총 크기)의 정렬된 리스트를 반환해요. key_type은 'filename', 'lineno', 'traceback' 중 하나이며 누적 여부에 따라 결과가 달라집니다.
snapshot.compare_to(old_snapshot, key_type, cumulative=False) — 이 스냅샷과 old_snapshot을 비교해 그 사이의 차이를 StatisticDiff의 정렬된 리스트로 반환해요. 'filename', 'lineno', 'traceback' 키로, 얼마나 많이 증가/감소했는지 알 수 있어요.
snapshot.filter_traces(filters) — 메모리 할당 블록을 필터링해 여러 필터에 매칭하는 블록만 남긴 새 Snapshot 객체를 만들어요. 전체 트레이스를 순회하며 필터를 확인합니다.
메모리 통계 (Statistics)
class tracemalloc.Statistic — 저장된 Snapshot.statistics()의 통계. 속성: key(식별 문자열), count(변경된 블록 수), size(블록들의 총 크기). Statistic은 같음 비교가 가능하고 __hash__를 지원해요.
class tracemalloc.StatisticDiff — 다른 스냅샷을 비교한 통계. Statistic의 속성에 더해 count_diff, size_diff를 가져요.
class tracemalloc.Trace — 하나의 메모리 할당 블록의 추적. 속성: size, traceback. Trace는 __eq__, __hash__를 지원합니다.
class tracemalloc.Traceback — Trace 객체의 스택 추적 프레임 목록. Traceback은 __eq__, __hash__를 지원합니다.
class tracemalloc.Frame — 하나의 스택 추적 프레임. 속성: filename(파일 이름), lineno(줄 번호), name(함수 이름).
예시 (Examples)
다음 예제는 이 모듈의 기본적인 사용 방법을 보여줘요.
import tracemalloc
tracemalloc.start()
# ... run your application ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
print("[ Top 10 ]")
for stat in top_stats[:10]:
print(stat)
다른 스냅샷과 비교해 메모리 증가 원인을 찾는 예:
import tracemalloc
tracemalloc.start()
# start of your app
snapshot1 = tracemalloc.take_snapshot()
# ... more allocations ...
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
print("[ Top 10 differences ]")
for stat in top_stats[:10]:
print(stat)