Cpython 런타임이 메모리 관리를 알아서 해주기 때문에 메모리 사용 혹은 누수를 알 수가 없다.
gc 내장 모듈 사용
import os
class MyObject:
def __init__(self):
self.data = os.urandom(100)
def get_data():
values = []
for _ in range(100):
obj = MyObject()
values.append(obj)
return values
def run():
deep_values = []
for _ in range(100):
deep_values.append(get_data())
return deep_values
gc 내장 모듈 사용해서 실행 중 생성한 객체의 수와 생성한 객체 중 일부를 출력
import gc
found_objects = gc.get_objects()
print('이전:', len(found_objects))
import waste_memory
hold_reference = waste_memory.run()
found_objects = gc.get_objects()
print('이후:', len(found_objects))
for obj in found_objects[:3]:
print(repr(obj)[:100])
단점: 객체가 어떻게 할당됐는지 알려주지 않는다.
해결: tracemalloc라는 내장 모듈 사용
tracemalloc는 객체를 자신이 할당된 장소와 연결을 시켜준다.
ㅁ메모리 사용의 이전과 이후 스냅샷을 만들어서 서로 비교하면서 변경 부분 체크
import tracemalloc
tracemalloc.start(10)# 스택 깊이 설정
time1 = tracemalloc.take_snapshot()# 이전 스냅샷
import waste_memory
x = waste_memory.run()# 메모리의 사용을 디버깅
time2 = tracemalloc.take_snapshot() #이후 스냅샷
stats = time2.compare_to(time1, 'lineno') #두 스냅샷 비교
for stat in stats[:3]:
print(stat)
출력에 있는 크기와 카운트 레이블을 보면 프로그램에서 메모리를 주로 사용하는 객체와 이런 객체를 할당한 소스 코드 명확화
tracemalloc 모듈은 각 할당의 전체 스택 트레이스를 출력
#메모리를 가장 많이 사용하는 곳의 스택 트레이스
import tracemalloc
time1 = tracemalloc.take_snapshot()
import waste_memory
x = waste_memory.run()
time2 = tracemalloc.take_snapshot()
stats = time2.compare_to(time1, 'traceback')
top = stats[0]
print('가장 많이 사용하는 부분운:')
print('\n'.join(top.traceback.format()))
파이썬 프로그램이 메모미를 사용하고 누수하는 양상을 이해하기 어렵다.
gc모듈은 어떤 객체가 존재하는지 이해할 때는 도움이 되지만, 객체가 어떻게 할당됐느지 파악할 수 있는 정보는 제공하지 않는다.
tracemalloc 내장 모듈은 프로그램이 메모리를 사용하는 이유를 알고 싶을 때 쓸 수 있는 강력한 도구