프로세스에서 메모리 누수를 디버깅하기 위해 perfmon windows 유틸리티를 사용하려고합니다.
이것이 perfmon이 다음과 같은 용어를 설명하는 방법입니다.
작업 집합 은이 프로세스의 작업 집합의 현재 크기 (바이트)입니다. 작업 세트는 프로세스의 스레드가 최근에 터치 한 메모리 페이지 세트입니다. 컴퓨터의 사용 가능한 메모리가 임계 값을 초과하면 사용하지 않더라도 프로세스의 작업 세트에 페이지가 남습니다. 사용 가능한 메모리가 임계 값 아래로 떨어지면 작업 세트에서 페이지가 잘립니다. 필요한 경우 메인 메모리를 떠나기 전에 작업 세트로 소프트 오류가 발생합니다.
가상 바이트 는 프로세스가 사용중인 가상 주소 공간의 현재 크기 (바이트)입니다. 가상 주소 공간을 사용한다고해서 반드시 디스크 나 기본 메모리 페이지를 사용하는 것은 아닙니다. 가상 공간은 유한하며 프로세스는 라이브러리를로드하는 기능을 제한 할 수 있습니다.
개인 바이트 는이 프로세스가 할당 한 다른 프로세스와 공유 할 수없는 메모리의 현재 크기 (바이트)입니다.
이것들은 내가 가진 질문입니다.
프로세스가 공유 라이브러리를 포함하지 않고 누출이 발생하면 프로세스 자체에서 발생하기 때문에 프로세스에 누출이 있는지 확인하기 위해 측정 해야하는 개인 바이트입니까?
프로세스가 소비 한 총 메모리는 얼마입니까? 가상 바이트입니까 아니면 가상 바이트와 작업 세트의 합입니까?
프라이빗 바이트, 워킹 세트 및 가상 바이트 사이에 관계가 있습니까?
메모리 사용에 대한 더 나은 아이디어를 제공하는 다른 도구가 있습니까?
답변
이 질문에 대한 짧은 대답 은 이러한 값 중 어느 것도 실행 파일이 실제로 사용하고있는 메모리 양을 나타내는 신뢰할 수있는 지표가 아니며 메모리 누수를 디버깅하는 데 실제로 적합한 값은 없다는 것입니다.
개인 바이트 는 프로세스 실행 파일이 요청한 메모리의 양을 의미하며 반드시 실제로 사용 하는 양은 아닙니다 . 메모리로 매핑 된 파일 (예 : 공유 DLL)을 (일반적으로) 제외하기 때문에 “비공개”입니다. 그러나 여기에 캐치가 있습니다 . 파일에 의해 할당 된 메모리를 반드시 배제 할 필요는 없습니다 . 개인 바이트의 변경이 실행 파일 자체에 의한 것인지 또는 링크 된 라이브러리에 의한 것인지를 알 수있는 방법은 없습니다. 개인 바이트도 독점적으로 실제 메모리가 아닙니다 . 디스크 또는 대기 페이지 목록으로 페이징 될 수 있습니다 (즉, 더 이상 사용되지 않지만 아직 페이징되지 않음).
작업 집합 은 프로세스에서 사용 하는 총 실제 메모리 (RAM)를 나타냅니다 . 그러나 개인 바이트와 달리 여기에는 메모리 매핑 파일 및 기타 다양한 리소스가 포함되므로 개인 바이트보다 측정 정확도가 떨어집니다. 이것은 작업 관리자의 “Mem Usage”에보고 된 것과 동일한 값이며 최근 몇 년 동안 끝없는 혼란의 원천이었습니다. 작업 세트의 메모리는 페이지 결함없이 처리 될 수 있다는 점에서 “물리적”입니다. 그러나, 대기 페이지 목록입니다 또한 물리적으로 메모리에 있지만 작업 집합에보고, 당신은 응용 프로그램을 최소화 할 때 갑자기 드롭 “메모리 사용”을 볼 수 있습니다 이유입니다.
가상 바이트 는 전체 프로세스가 차지하는 총 가상 주소 공간 입니다. 이것은 메모리 매핑 된 파일 (공유 DLL)을 포함한다는 점에서 작업 세트와 비슷하지만 대기 목록의 데이터와 이미 페이징 된 데이터와 디스크의 페이지 파일에있는 데이터도 포함합니다. 로드가 많은 시스템의 모든 프로세스에서 사용하는 총 가상 바이트는 머신의 실제 메모리보다 훨씬 많은 메모리를 추가합니다.
관계는 다음과 같습니다.
- 프라이빗 바이트는 앱이 실제로 할당 한 것이지만 페이지 파일 사용량을 포함합니다.
- 작업 세트는 비 페이징 개인 바이트와 메모리 매핑 파일입니다.
- 가상 바이트는 작업 세트와 페이징 된 개인 바이트 및 대기 목록입니다.
여기 또 다른 문제가 있습니다. 그냥 공유 라이브러리는 잠재적 인 오탐 (false positive)로 이어지는 응용 프로그램 모듈 내부 메모리를 할당 할 수 있습니다 앱의 전용 바이트에보고, 당신 또한 내부 메모리를 할당 끝낼 수 있습니다 응용 프로그램 공유 false로 이어지는, 모듈 제외 . 즉, 실제로 응용 프로그램에서 개인 바이트에 절대로 나타나지 않는 메모리 누수가 발생할 수 있습니다. 가능하지는 않지만 가능합니다.
개인 바이트는 실행 파일이 사용중인 메모리의 대략적인 근사치 이며 메모리 누수 가능성이있는 후보 목록을 좁히는 데 사용할 수 있습니다 . 지속적으로 그리고 끊임없이 숫자가 증가하고 증가하는 것을 볼 경우 해당 프로세스에서 누수가 있는지 확인하고 싶을 것입니다. 그러나 이것은 누출이 있음 을 증명할 수 없습니다 .
Windows에서 메모리 누수를 감지 / 수정하는 가장 효과적인 도구 중 하나는 실제로 Visual Studio입니다 (링크는 제품 페이지가 아니라 메모리 누수를 위해 VS를 사용하는 페이지로 이동 함). 합리적인 정화 는 또 다른 가능성입니다. 또한 Microsoft는 이 주제에 대한보다 일반적인 모범 사례 문서 를 보유하고 있습니다 . 이 이전 질문 에 더 많은 도구가 나열되어 있습니다.
이것이 몇 가지 사항을 해결하기를 바랍니다. 메모리 누수를 추적하는 것은 디버깅에서 가장 어려운 작업 중 하나입니다. 행운을 빕니다.
답변
perfmon, 작업 관리자 또는 이와 유사한 도구를 사용하여 메모리 누수를 확인해서는 안됩니다. 트렌드를 식별하는 데는 좋지만 다른 것은 아닙니다. 그들이 절대 용어로보고하는 숫자는 너무 모호하고 집계되어 메모리 누수 감지와 같은 특정 작업에 유용하지 않습니다.
이 질문에 대한 이전 답변은 다양한 유형이 무엇인지에 대한 훌륭한 설명을 제공했습니다.
도구 권장 사항에 대해 묻습니다. Memory Validator를 권장합니다. 수십억 개의 메모리 할당을 수행하는 응용 프로그램을 모니터링 할 수 있습니다.
http://www.softwareverify.com/cpp/memory/index.html
면책 조항 : Memory Validator를 설계했습니다.
답변
perfmon 카운터의 정의는 처음부터 깨졌으며 어떤 이유로 수정하기가 너무 어려워 보입니다.
Windows 메모리 관리에 대한 좋은 개요는 MSDN의 ” 메모리 관리 미스테리 공개 ” 비디오에서 볼 수 있습니다 . 메모리 누수를 추적하는 데 필요한 것 (예 : 작업 세트 관리)보다 더 많은 주제를 다루지 만 관련 항목에 대해서는 충분히 자세히 설명합니다.
perfmon 카운터 설명에 대한 문제점에 대한 힌트를 제공하기 위해 MSDN의 ” Private Bytes Performance Counter-Beware! “의 개인 바이트에 대한 내부 기사는 다음과 같습니다.
Q : 개인 바이트는 개인 바이트가 아닌 경우는 언제입니까?
A : 상주하지 않을 때.
Private Bytes 카운터는 프로세스의 커밋 요금을보고합니다. 즉, 스왑 파일이 스왑 아웃 된 경우 개인 메모리의 내용을 보유하기 위해 스왑 파일에 할당 된 공간의 양입니다. 참고 : 나는 예약되지 않은 상태에서 가상 메모리와 혼동 될 수 있기 때문에 “예약 됨”이라는 단어를 피하고 있습니다.
MSDN의 ” 성능 계획 “에서 :
3.3 개인 바이트
3.3.1 설명
개인용 메모리는 다른 프로세스와 공유 할 수없는 프로세스에 할당 된 메모리로 정의됩니다. 이 메모리는 여러 프로세스가 머신에서 실행될 때 공유 메모리보다 비쌉니다. (전통적인) 관리되지 않는 dll의 개인 메모리는 일반적으로 C ++ 정적으로 구성되며 dll의 전체 작업 집합의 5 % 정도입니다.
답변
흥미로운 토론이 여기에 있습니다 : http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/
이 스레드의 나의 이해는 해방 작은 할당이 있다는 것입니다 개인 바이트 또는 작업 세트에 반영되지 않습니다.
간단히 말해 :
내가 전화하면
p=malloc(1000);
free(p);
프라이빗 바이트는 할당 해제가 아닌 할당 만 반영합니다.
내가 전화하면
p=malloc(>512k);
free(p);
그런 다음 개인 바이트는 할당 및 할당 해제를 올바르게 반영합니다.