PoolMon을 사용하여 커널 모드 메모리 누수 찾기
커널 모드 메모리 누수로 의심되는 경우 PoolMon 도구를 사용하여 누수와 연결된 풀 태그를 확인할 수 있습니다.
poolMon(Poolmon.exe)은 풀 태그 이름으로 풀 메모리 사용량을 모니터링합니다. 이 도구는 WDK(Windows 드라이버 키트)에 포함되어 있습니다. 자세한 내용은 PoolMon을 참조하세요.
GFlags 풀 설정
특수 풀과 같은 일부 GFlags 설정은 메모리 풀 사용 방식에 영향을 줍니다. 자세한 내용은 GFlags 및 특수 풀 구성을 참조하세요.
PoolMon 사용
PoolMon 헤더는 페이징된 총 및 페이징되지 않은 풀 바이트를 표시합니다. 열에는 각 풀 태그에 대한 풀 사용이 표시됩니다. 디스플레이는 몇 초마다 자동으로 업데이트됩니다. 예를 들면 다음과 같습니다.
Memory: 16224K Avail: 4564K PageFlts: 31 InRam Krnl: 684K P: 680K
Commit: 24140K Limit: 24952K Peak: 24932K Pool N: 744K P: 2180K
## Tag Type Allocs Frees Diff Bytes Per Alloc
CM Paged 1283 ( 0) 1002 ( 0) 281 1377312 ( 0) 4901
Strg Paged 10385 ( 10) 6658 ( 4) 3727 317952 ( 512) 85
Fat Paged 6662 ( 8) 4971 ( 6) 1691 174560 ( 128) 103
MmSt Paged 614 ( 0) 441 ( 0) 173 83456 ( 0) 482
PoolMon에는 다양한 조건에 따라 출력을 정렬하는 명령 키가 있습니다. 데이터를 사용하려면 각 명령과 연결된 문자를 선택합니다. 각 명령이 작동하려면 몇 초 정도 걸립니다.
정렬 명령은 다음과 같습니다.
명령 키 | 작업 |
---|---|
P | 표시된 태그를 페이징이 아닌 풀 바이트, 페이징된 풀 바이트 또는 둘 다로 제한합니다. 이러한 각 옵션을 순서대로 P 주기를 반복적으로 누릅니다. |
B | 최대 바이트 사용량별로 태그를 정렬합니다. |
M | 태그를 최대 바이트 할당별로 정렬합니다. |
T | 태그 이름을 기준으로 태그를 사전순으로 정렬합니다. |
E | 표시가 아래쪽에 페이징된 합계와 페이징이 아닌 합계를 포함하도록 합니다. |
A | 태그를 할당 크기별로 정렬합니다. |
F | 무료 작업별로 태그를 정렬합니다. |
S | 할당과 해제 간의 차이로 태그를 정렬합니다. |
Q | PoolMon을 종료합니다. |
PoolMon에서 드라이버 이름 표시
PoolMon /g 매개 변수를 사용하여 각 풀 태그를 할당하는 Windows 구성 요소 및 일반적으로 사용되는 드라이버의 이름을 표시할 수 있습니다. 특정 태그의 할당에 문제가 있는 경우 이 기능을 사용하면 잘못된 구성 요소 또는 드라이버를 식별할 수 있습니다.
구성 요소와 드라이버는 디스플레이에서 가장 오른쪽에 있는 Mapped_Driver 열에 나열됩니다. Mapped_Driver 열의 데이터는 WDK와 함께 설치된 파일인 pooltag.txt 가져옵니다.
다음 명령은 /g 매개 변수를 사용하여 Mapped_Driver 열을 추가하는 방법을 보여줍니다.
poolmon /g "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\triage\pooltag.txt"
특정 풀 표시
/i 매개 변수를 사용하여 특정 문자열로 시작하는 풀 태그(예: Hid)를 표시합니다.
poolmon /iHid? /g "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\triage\pooltag.txt"
Memory:33473120K Avail:20055132K PageFlts: 5 InRam Krnl:10444K P:1843072K
Commit:15035764K Limit:67027552K Peak:16677444K Pool N:1023400K P:1955448K
System pool information
Tag Type Allocs Frees Diff Bytes Per Alloc Mapped_Driver
HidC Paged 1667 ( 0) 1659 ( 0) 8 896 ( 0) 112 [hidclass.sys - HID Class d
HidC Nonp 17375 ( 0) 17256 ( 0) 119 19808 ( 0) 166 [hidclass.sys - HID Class d
HidP Nonp 1014 ( 0) 998 ( 0) 16 6704 ( 0) 419 [hidparse.sys - HID Parser]
PoolMon 유틸리티를 사용하여 메모리 누수 찾기
다음은 PoolMon 유틸리티를 사용하여 메모리 누수 문제를 찾는 한 가지 방법입니다.
PoolMon을 시작합니다.
페이징되지 않은 풀에서 누출이 발생하는 것으로 확인되면 P를 한 번 선택합니다. 페이징 풀에서 발생하는 것으로 확인되면 P를 두 번 선택합니다. 모르는 경우 P를 선택하지 않으므로 두 종류의 풀이 모두 포함됩니다.
최대 바이트 사용을 기준으로 표시를 정렬하려면 B를 선택합니다.
테스트를 시작합니다. 예를 들어 스크린샷을 찍고 저장하여 화면에서 출력을 복사합니다.
반시간마다 새 스크린샷을 찍습니다. 스크린샷을 비교하여 어떤 태그의 바이트가 증가하고 있는지 확인합니다.
테스트를 중지하고 몇 시간을 기다립니다. 이 시간에 해제된 태그의 양을 확인합니다.
일반적으로 애플리케이션이 안정적인 실행 상태에 도달하면 메모리와 사용 가능한 메모리를 동일한 속도로 할당합니다. 메모리를 해제하는 것보다 더 빨리 할당하면 시간이 지남에 따라 메모리 사용이 증가합니다. 이는 종종 메모리 누수임을 나타냅니다.
누수 해결
누수와 관련된 풀 태그를 결정한 후 누수에 대해 알아야 할 모든 것이 있을 수 있습니다. 누출을 일으키는 할당 루틴의 특정 instance 확인해야 하는 경우 커널 디버거를 사용하여 커널 모드 메모리 누수 찾기를 참조하세요.