ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION1172 / 1500
언어·런타임난이도 중하5분 답변 목표 · 보강본

CPython 객체를 사용하던 외부 참조를 지웠는데 객체끼리 서로를 참조하고 있습니다. 메모리는 언제 회수되며 파일 닫기도 그 시점에 맡겨도 되나요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

CPython에서는 객체에 대한 참조가 사라져 참조 카운트가 0이 되면 보통 즉시 객체 정리가 시작됩니다. 하지만 객체 A가 B를, B가 A를 가리키고 외부에서 두 객체에 접근할 수 없게 되면 각 카운트가 0이 되지 않습니다. 이 순환 참조는 별도의 cyclic garbage collector가 추적 가능한 컨테이너를 검사해 도달 불가능한 묶음을 찾을 때 회수됩니다. 그러므로 “참조 카운트가 있으니 순환도 즉시 정리된다”는 설명은 틀립니다.

참조 카운트와 순환 그래프

순환 GC의 실행 시점과 비용은 구현·버전에 따른 임계값과 수집 활동의 영향을 받으며, del을 호출했다고 곧바로 모든 메모리가 운영체제로 돌아가는 것도 아닙니다. 객체가 정리되어도 Python 할당자가 재사용할 수 있고 프로세스 RSS는 유지될 수 있습니다. 더 중요한 점은 메모리 회수와 파일·소켓·락 같은 외부 자원의 반납이 같은 계약이 아니라는 것입니다.

from io import StringIO

with StringIO("ok") as stream:
    print(stream.read())
print(stream.closed)

자원 종료의 명시성

출력은 ok와 True입니다. 파일처럼 명시적 종료가 필요한 자원은 참조 카운트나 GC 시점에 기대지 말고 with의 컨텍스트 매니저로 성공·예외 여부와 관계없이 닫겠습니다. 메모리 증가가 보이면 순환 참조만 의심하지 말고 살아 있는 전역·캐시·콜백, 할당자 재사용, 외부 자원 누수를 각각 계측해 구분하겠습니다.

선택 기준과 검증

del은 이름 바인딩 하나만 제거하며 전역·캐시·콜백이 가진 참조까지 끊지 않습니다. 순환 GC가 그래프를 찾더라도 소멸자와 외부 자원 정리 순서를 정상 close 계약으로 대체해 주지는 않습니다. CPython 3.11/3.12에서 gc 통계·힙 보유·RSS·열린 파일 수를 같은 부하로 수집해 회수 지연과 실제 누수를 나누겠습니다.

참조 카운트는 각 참조가 없어지는 시점에 정리를 시작하기 쉬운 대신 참조 증감 비용을 냅니다. 순환에서는 내부 참조 때문에 카운트가 남으므로 별도의 순환 탐색이 필요합니다. del은 이름뿐 아니라 컨테이너 항목이나 속성을 지우는 문법에도 쓰일 수 있지만, 어느 경우든 지운 경로 외에 다른 참조가 남아 있는지 확인해야 실제 도달성을 판단할 수 있습니다.

__del__에 복잡한 외부 정리를 몰아넣으면 예외 처리·실행 시점·객체 부활 같은 문제가 생길 수 있습니다. 특히 정리 코드가 객체를 전역에 다시 저장하면 수명이 다시 이어질 수 있어 단순히 참조 카운트가 줄었다는 로그만으로 완료를 선언하기 어렵습니다. with는 정상적으로 블록을 벗어나거나 예외가 전파될 때 __exit__를 호출하는 계약이며 프로세스 강제 종료까지 실행을 보장하지 않습니다. 중요한 외부 상태는 재시작 복구도 마련하겠습니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • 참조 카운트 0과 순환 GC를 구분한다.
  • 객체 회수·RSS·외부 자원 수명을 따로 본다.
  • with·weakref·힙 관측으로 누수를 분해한다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 참조 카운트만으로 순환 참조도 즉시 정리된다고 말한다.
  • GC가 실행되면 RSS가 반드시 OS로 돌아간다고 설명한다.
  • 파일·소켓을 객체 소멸 시점까지 열어 두어도 안전하다고 가정한다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

원리부터 공부하고 싶다면

답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.

← 전체 질문 보기