Python 가비지 콜렉션 관련 질문입니다.

객체를 리스트로 저장할 때 가비지 콜렉션 관련 질문인데요,

alist = []
alist.append(SimpleClass())

...

alist = []

위와 같이 list에 객체를 삽입한 후, 사용이 완료되었을 때 list 를 초기화 해주는 경우에 객체가 가비지 콜렉션이 되나요? (즉, 객체가 없어지나요?) 아니면 명시적으로 삭제를 해주어야 하는지 궁금합니다.

1답변

  • 초기화할 필요는 없습니다.

    파이썬의 gc 알고리듬은 간단한 편(자바와 같이 참조되는 횟수에 따라 세대별로 프로모션되는 구조)입니다. 기본적인 레퍼런스 카운팅(이때는 GC가 동작하는 것이 아닙니다.참조계수가 0 이면 삭제입니다.)과 레퍼런스 카운팅으로 제거못하는 경우 대표적으로 순환참조(이때 GC사용)등을 처리하는 경우로 되어 있습니다. 또한 gc의 경우 문제가 되는 것이 바로 fragment 처리 입니다.

    객체들이 큰것과 작은것이 heap 에 쌓이게 되고 gc에 의해 정리되고 다시 할당하고 하다보면 빈틈이 생기기 마련입니다. 이 빈틈이 많아지면 빈틈보다 큰 객체가 할당될 때 메모리는 남아 있으나 큰 객체를 할당 할 수 없어 메모리 오류가 발생하게 됩니다.

    jvm에서는 이 문제를 해결하기 위해 compacting 과정이 있습니다. 즉 mark and sweep, compacting 과정을 수행합니다. 가비지를 mark 하고 삭제(sweep)를 합니다. 그리고 빈틈을 없애기 위해 compacting 과정을 거쳐 객체들을 다시 순서대로 재배치를 합니다. 그렇게 되면 빈틈이 사라지게 되어 fragment 문제를 해결할 수 있습니다. 물론...compacting 과정이 수행될 때는 stop the world 즉 프로그램 임시 멈춤 상태입니다. 당연하겠지요...객체를 옮기면서 메모리 주소가 바뀌므로 수행중에는 할 수 없는 작업입니다.

    그럼 파이썬은 어떻해 처리할까요... 파이썬은 block pool 이 있고 그 pool 에는 8, 16, 24...512 크기로 8의 배수로 메모리 블럭들이 있으며 메모리 요청이 있으면 그 적당한 크기의 블럭 단위로 할당하게 됩니다. 즉 8바이트 보다 작으면 8바이트 블럭 1개로 할당합니다. 즉 8바이트보다 크면 크기에 맞춰 32 바이트 블럭 몇개, 8바이트 블럭 몇개 해서 필요한 만큼의 블럭을 할당하게 됩니다. 이런 경우 gc가 일어나면 블럭크기로 반환될 것이므로 단편화를 방지 할 수 있습니다.

    이제 답변인데...초기화안해도 알아서 정리가 됩니다.

    • main loop에서 돌리는 프로그램이라 초기화 안해주면 객체가 그대로 남아있습니다. RK 2018.11.8 16:39
    • 남아있다는 문제와 GC문제는 다른 차원의 문제입니다. 로직상 삭제를 해야 되는 것이면 당연히 명시적 삭제를 해야 하는 것이 맞습니다만 사용안할 객체라면 알아서 GC대상이 됩니다. 정영훈 2018.11.8 17:42

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.