eryksun 님은 1 번 질문에 대한 답변을 보았으며, 3 번 질문 (원본 # 4)에 답변했지만 이제 2 번 질문에 답변하겠습니다 :
특히 50.5mb를 릴리스하는 이유는 무엇을 기준으로 릴리스됩니까?
그것이 기반으로하는 것은 궁극적으로 파이썬 내부의 일련의 우연의 일치이며 malloc
예측하기가 매우 어렵습니다.
첫째, 메모리를 측정하는 방법에 따라 실제로 메모리에 매핑 된 페이지 만 측정 할 수 있습니다. 이 경우, 호출기가 페이지를 교체 할 때마다 메모리가 해제되지 않았더라도 메모리가 "사용 가능"으로 표시됩니다.
또는 사용중인 페이지를 측정하고있을 수 있지만 할당되지는 않았지만 터치하지 않은 페이지 (리눅스와 같이 낙관적으로 과도하게 할당 된 시스템), 할당되었지만 태그가 지정된 페이지 MADV_FREE
등을 계산하거나 계산하지 않을 수 있습니다 .
실제로 할당 된 페이지 (실제로는 매우 유용한 일이 아니지만 요청하는 것 같습니다)를 측정하고 있고 페이지가 실제로 할당 해제 된 경우 두 가지 상황이 발생할 수 있습니다. brk
현재는 데이터 세그먼트를 축소하는 데 사용 되거나 이와 동등하거나 (매우 드물게) munmap
매핑 된 세그먼트를 해제하는 데 사용 하거나 유사합니다. (매핑 된 세그먼트의 일부를 해제하는 방법이 있다는 점에서 이론적으로 후자에 대한 작은 변형이 있습니다. 예를 들어, 즉시 매핑을 해제 MAP_FIXED
하는 MADV_FREE
세그먼트에 대해 도용하십시오 .)
그러나 대부분의 프로그램은 메모리 페이지에서 항목을 직접 할당하지 않습니다. 그들은 malloc
스타일 할당자를 사용합니다 . 을 호출 free
하면 할당 자 free
(또는 데이터 세그먼트의 마지막 N 페이지)에서 마지막 라이브 객체를 사용하는 경우 할당자가 OS로 페이지를 릴리스 만 할 수 있습니다 . 애플리케이션이이를 합리적으로 예측하거나 미리 발생한 것을 감지 할 수있는 방법은 없습니다.
CPython은이를 더욱 복잡하게 만듭니다. 사용자 지정 메모리 할당 자 위에 사용자 지정 2 수준 개체 할당자가 malloc
있습니다. ( 자세한 설명 은 소스 주석 을 참조하십시오 .) 또한 C API 수준에서도 훨씬 적은 Python에서도 최상위 수준 개체의 할당이 취소되는 시점을 직접 제어 할 수도 없습니다.
따라서 객체를 릴리즈 할 때 OS에 메모리를 릴리즈할지 여부를 어떻게 알 수 있습니까? 글쎄, 먼저 GC가 할당을 해제 할 수 있도록 마지막 참조 (알지 못한 내부 참조 포함)를 발표했음을 알아야합니다. (다른 구현과 달리, 적어도 CPython은 허용되는 즉시 객체를 할당 해제합니다.) 일반적으로 다음 레벨에서 적어도 두 가지를 할당 취소합니다 (예 : 문자열의 경우 PyString
객체를 해제 하고 문자열 버퍼 ).
당신이 경우에 할 이 객체 저장의 블록 할당을 해제 다음 수준 아래로 발생 여부를 알고, 객체를 할당 해제, 당신은 그것을 구현 얼마나뿐만 아니라, 객체 할당의 내부 상태를 알아야합니다. (블록의 마지막 항목을 할당 해제하지 않으면 일어날 수 없으며, 심지어는 일어날 수 없습니다.)
당신이 경우 어떻게 이것이 원인인지 알고, 객체 저장의 블록을 할당 해제 free
전화를, 당신은 그것을 구현 얼마나뿐만 아니라의 PyMem 할당의 내부 상태를 알아야합니다. (다시 말해서, malloc
ed region 내에서 마지막 사용중인 블록을 할당 해제해야하며 , 그럴 경우에도 발생하지 않을 수 있습니다.)
에드 리전 을 수행 free
하는 경우 malloc
이로 인해 munmap
또는 이에 해당하는 (또는 brk
) 원인이되는지 알기 위해서는의 내부 상태와 malloc
구현 방법 을 알아야합니다 . 그리고 이것은 다른 플랫폼과 달리 플랫폼에 따라 다릅니다. (그리고 다시, 일반적으로 세그먼트 malloc
내 에서 마지막 사용 중을 할당 해제해야하며 mmap
, 그런 경우에도 발생하지 않을 수 있습니다.)
따라서 정확히 50.5MB가 릴리스 된 이유를 이해하려면 아래에서 위로 추적해야합니다. malloc
하나 이상의 free
호출을 할 때 왜 50.5mb에 해당하는 페이지를 매핑 해제 했 습니까? 플랫폼의을 읽고 malloc
다양한 테이블과 목록을 걸어 현재 상태를 확인해야합니다. (일부 플랫폼에서는 시스템 수준 정보를 사용할 수도 있습니다. 시스템 수준의 스냅 샷을 만들지 않고는 오프라인으로 검사하지 않으면 캡처 할 수 없지만 운 좋게도 일반적으로 문제가되지는 않습니다.) 위의 3 단계에서 동일한 작업을 수행하십시오.
따라서이 질문에 대한 유용한 답변은 "왜냐"입니다.
리소스 제한 (예 : 임베디드) 개발을 수행하지 않는 한 이러한 세부 사항에 신경 쓸 이유가 없습니다.
당신이 만약 되는 자원이 제한된 개발하고, 이러한 세부 사항을 아는 것은 쓸모가 없다; 이러한 모든 수준과 특히 mmap
응용 프로그램 수준에서 필요한 메모리를 중심으로 엔드 런을 수행 해야합니다 (간단하고 이해하기 쉬운 응용 프로그램 특정 영역 할당 자 사이에있을 수 있음).