Sandcorp샌드코프 · 웹·AI 제품 개발

새 프로젝트 받는 중 · 갱신 2026.11sandcorp.co.krGitHub

← 팁

메모리

오래 도는 루프의 지역 변수는 GC 루트다

while True 루프는 다음 메시지를 기다리는 동안에도 마지막으로 다룬 객체를 붙잡는다. 한 번의 처리를 함수로 빼면 참조가 함수 안에서 끝난다.

무한 수신 루프를 도는 워커에서, 처리를 마친 큰 객체가 해제되지 않고 메모리가 줄지 않는다. 레지스트리에서는 지웠는데 어딘가 참조가 남아 있다.

그 어딘가는 루프의 지역 변수다. while True 루프 안에서 마지막으로 대입한 변수는, 루프가 다음 메시지를 await로 기다리는 동안에도 그대로 살아 있다. 메시지가 뜸하면 몇 분이고 큰 객체를 붙잡는다. 실행 중인 프레임의 지역 변수는 GC의 루트라 다른 참조가 다 사라져도 해제되지 않는다.

한 번의 처리를 함수로 뺀다. 함수가 끝나면 그 안의 지역 변수가 사라지니 참조도 함께 끝난다.

# 나쁨: obj가 다음 메시지가 올 때까지 살아 있다
async def worker(queue):
    while True:
        event = await queue.get()
        obj = registry[event.key]
        handle(obj, event)

# 좋음: 참조가 dispatch 안에서 끝난다
async def dispatch(event):
    obj = registry[event.key]
    handle(obj, event)

async def worker(queue):
    while True:
        await dispatch(await queue.get())

del obj로 지워도 되지만, 분기마다 빠뜨리기 쉽다. 함수로 빼는 쪽이 실수하기 어렵다. 큰 객체를 다루는 워커·수신 루프라면 특히 챙긴다.

문의 →