본문으로 건너뛰기

[CPython 3.14] OrderedDict.popitem() 메모리 누수 수정 (backport)

PR 링크: python/cpython#146537 (3.14 backport) 원본 PR: python/cpython#145247 상태: Merged | 변경: +3 / -1

들어가며

이 PR은 OrderedDict.popitem() 메모리 누수 수정의 3.14 브랜치 backport입니다. 3.13 backport(#146538)와 동일한 수정이지만, odictobject.c의 행 번호가 다릅니다(3.14에서는 1168행, 3.13에서는 1148행).

핵심 코드 분석

Before:

// Objects/odictobject.c (3.14 branch, line 1168)
key = Py_NewRef(_odictnode_KEY(node));
value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
if (value == NULL)
    return NULL;    // key의 참조 카운트 감소 없이 반환 -> 메모리 누수!

After:

key = Py_NewRef(_odictnode_KEY(node));
value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
if (value == NULL) {
    Py_DECREF(key);  // 에러 경로에서도 key 참조 해제
    return NULL;
}

Py_NewRef로 증가시킨 참조 카운트를 에러 경로에서도 반드시 감소시켜야 합니다. 이를 누락하면 key 객체가 가비지 컬렉션되지 않습니다.

왜 이게 좋은가

  • 메모리 안전성: popitem()이 내부적으로 실패하는 edge case에서도 메모리가 올바르게 관리됩니다.
  • 3.14 릴리스 안정화: 차기 안정 릴리스인 3.14에 이 수정이 포함되어 출시됩니다.
  • C 확장 패턴: Py_NewRef + 조건부 반환 시 반드시 Py_DECREF를 에러 경로에 포함하는 패턴은 CPython 개발의 기본 원칙입니다.

정리

3.14 backport로, 3.13 버전(#146538)과 동일한 3줄 수정입니다. 참조 카운트 누수는 장기 실행 프로세스에서 점진적 메모리 증가를 유발하므로, 모든 지원 버전에 수정을 적용하는 것이 중요합니다.

참고 자료


이 포스트는 AI가 작성하였으며, 사실과 다를 수 있습니다. 정확한 정보는 원본 PR을 참고해 주세요.

댓글

관련 포스트

PR Analysis 의 다른글