다음을 통해 공유


PoolMon 예제

이 항목에는 다음 PoolMon 사용 예제가 포함되어 있습니다.

예제 1: PoolMon 출력 표시 및 정렬

예제 2: 드라이버 이름 표시

예제 3: 메모리 누수 감지

예제 4: 풀 메모리 누수 검사

예제 5: 터미널 서버 세션 모니터링

예제 1: PoolMon 출력 표시 및 정렬

이 예제에서는 PoolMon 디스플레이를 구성하는 다양한 방법을 설명합니다. 기본적으로 PoolMon은 모든 커널 메모리 할당을 태그 값별로 영숫자 순서로 표시합니다. 명령줄에서 또는 PoolMon이 실행되는 동안 디스플레이의 정렬 순서를 수정할 수 있습니다.

다음 명령은 PoolMon을 시작합니다.

poolmon

다음 명령은 PoolMon을 시작하고 사용 가능한 작업 수로 디스플레이를 정렬합니다.

poolmon /f

poolmon이 실행되는 동안 런타임 명령을 사용하여 디스플레이를 변경할 수 있습니다. 예를 들어 사용된 바이트 수를 기준으로 디스플레이를 정렬하려면 b 키를 누릅니다. 할당당 바이트 단위로 정렬하려면 m 키를 누릅니다.

다음 명령은 PoolMon을 시작하고 페이지가 없는 풀의 할당만 표시합니다.

poolmon /p

PoolMon이 실행되는 동안 p 키를 눌러 페이징된 풀, 페이지가 없는 풀 또는 둘 다에서 할당을 전환합니다.

PoolMon을 시작하고 특정 태그를 사용하여 할당에 대한 데이터를 표시하려면 /i 매개 변수를 사용합니다. 다음 명령은 AfdB 태그(데이터 버퍼에 afd.sys 사용되는 태그)를 사용하여 할당을 표시합니다.

poolmon /iAfdB

특정 태그가 있는 할당을 제외하려면 /x 매개 변수를 사용합니다. 다음 명령은 AfdB 태그가 없는 모든 할당을 표시합니다.

poolmon /xAfdB

별표(*) 및/또는 물음표(?)를 사용하여 동일한 문자가 있는 태그 집합을 지정할 수 있습니다. 다음 명령은 afd.sys 사용하는 태그인 Afd로 시작하는 풀 태그가 있는 할당을 표시합니다.

poolmon /iAfd*

PoolMon 시작 명령에는 여러 /i/x 매개 변수가 포함될 수 있습니다. 다음 명령은 CcBc 태그가 있는 할당을 제외하고 Aud로 시작하는 태그와 Cc로 시작하는 4자 태그가 있는 할당을 표시합니다.

poolmon /iAud* /iCc?? /xCcBc

업데이트 간의 값 변경에 따라 PoolMon 디스플레이를 정렬할 수도 있습니다. /( 매개 변수는 PoolMon을 정렬 기준 변경 모드로 설정합니다.

다음 명령은 Afd로 시작하는 태그가 있는 할당을 표시하고 할당 변경에 따라 정렬합니다. /a 매개 변수를 사용하여 할당 수와 /) 매개 변수를 정렬하여 할당 수의 변경으로 정렬합니다.

poolmon /iAfd* /( /a

/( 매개 변수 및 괄호 키는 토글 스위치입니다. PoolMon이 정렬 기준 변경 모드인 경우 모든 정렬 명령을 값의 변경에 따라 정렬하는 명령으로 해석합니다. 괄호 키를 다시 누르면 값을 기준으로 정렬됩니다.

예제 2: 드라이버 이름 표시

PoolMon /g 매개 변수를 사용하여 각 풀 태그를 할당하는 Windows 구성 요소 및 일반적으로 사용되는 드라이버의 이름을 표시할 수 있습니다. 특정 태그의 할당에 문제가 있는 경우 이 기능을 사용하면 잘못된 구성 요소 또는 드라이버를 식별할 수 있습니다.

구성 요소와 드라이버는 디스플레이에서 가장 오른쪽에 있는 Mapped_Driver 열에 나열됩니다. Mapped_Driver 열의 데이터는 WDK와 함께 설치된 파일인 pooltag.txt 가져옵니다.

다음 명령은 NtF로 시작하는 태그로 할당된 메모리를 표시합니다. (물음표 문자(?)를 와일드카드로 사용합니다. /g 매개 변수는 Mapped_Driver 열을 추가합니다.

poolmon /iNtF? /g "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\triage\pooltag.txt"

풀몬과 동일한 위치에 pooltag.txt 파일을 복사할 수도 있습니다. 이렇게 하면 이 사용이 허용됩니다.

poolmon /iNtF? /g

결과 표시는 NtF에서 시작하는 태그가 있는 할당을 나열합니다. 디스플레이에서 가장 오른쪽 열인 Mapped_Driver NTFS 파일 시스템의 드라이버인 ntfs.sys 메모리가 할당되었음을 보여 줍니다. 이 경우 pooltag.txt NTFS 할당에 대한 원본 파일을 포함하므로 디스플레이가 더욱 구체적입니다.

 Memory:  260620K Avail:   65152K  PageFlts:    85   InRam Krnl: 2116K P:19560K
 Commit: 237688K Limit: 640916K Peak: 260632K            Pool N: 8500K P:33024K
 System pool information
 Tag  Type     Allocs            Frees            Diff   Bytes      Per Alloc  Mapped_Driver

 NtFA Nonp       9112 (   0)      9112 (   0)     0       0 (     0)      0 [ntfs.sys  -  AttrSup.c]
 NtFB Paged      3996 (   0)      3986 (   0)    10  252088 (     0)  25208 [ntfs.sys  -  BitmpSup.c]
 NtFC Paged   1579279 (   0)   1579269 (   0)    10     640 (     0)     64 [ntfs.sys  -  Create.c]
 NtFD Nonp         13 (   0)        13 (   0)     0       0 (     0)      0 [ntfs.sys  -  DevioSup.c]
 NtFF Paged      1128 (   0)      1128 (   0)     0       0 (     0)      0 [ntfs.sys  -  FileInfo.c]
 NtFI Nonp        152 (   0)       152 (   0)     0       0 (     0)      0 [ntfs.sys  -  IndexSup.c]
 NtFL Nonp      68398 (   0)     68390 (   0)     8   27280 (     0)   3410 [ntfs.sys  -  LogSup.c]
 NtFS Paged      2915 (   0)      2614 (   0)   301   80192 (     0)    266 [ntfs.sys  -  SecurSup.c]
 NtFa Paged       838 (   0)       829 (   0)     9     288 (     0)     32 [ntfs.sys  -  AllocSup.c]
 NtFd Paged    137696 (   0)    137688 (   0)     8     720 (     0)     90 [ntfs.sys  -  DirCtrl.c]
 NtFf Nonp          2 (   0)         1 (   0)     1      40 (     0)     40 [ntfs.sys  -  FsCtrl.c]
 NtFs Nonp      48825 (   0)     47226 (   0)  1599   64536 (     0)     40 [ntfs.sys  -  StrucSup.c]
 NtFv Paged       551 (   0)       551 (   0)     0       0 (     0)      0 [ntfs.sys  -  ViewSup.c]

Pooltag.txt 광범위하지만 Windows에서 사용되는 모든 태그의 전체 목록은 아닙니다. 디스플레이에 표시되는 태그가 pooltag.txt 포함되지 않은 경우 PoolMon은 태그의 Mapped_Driver 열에 "알 수 없는 드라이버"를 표시합니다.

다음 예제에서는 32비트 시스템에서 이 메서드를 보여 줍니다.

다음 명령은 /i 매개 변수를 사용하여 MEM으로 끝나는 태그가 있는 할당을 나열합니다. /g 매개 변수는 pooltag.txt 파일의 디스플레이에 드라이버 이름을 추가합니다.

poolmon /i?MEM /g

결과 표시에는 MEM으로 끝나는 태그가 있는 할당이 나열됩니다. 그러나 MEM 태그는 pooltag.txt 포함되지 않으므로 드라이버 이름 대신 Mapped_Driver 열에 "알 수 없는 드라이버"가 나타납니다.

 Tag  Type        Allocs          Frees      Diff   Bytes      Per Alloc    Mapped_Driver

 1MEM Nonp       1 (   0)         0 (   0)     1    3344 (     0)   3344   Unknown Driver
 2MEM Nonp       1 (   0)         0 (   0)     1    3944 (     0)   3944   Unknown Driver
 3MEM Nonp       3 (   0)         0 (   0)     3     248 (     0)     82   Unknown Driver

다음 명령은 PoolMon을 시작합니다. /i 매개 변수를 사용하여 MEM으로 끝나는 태그가 있는 할당을 나열합니다.

poolmon /i?MEM 

다음 명령은 Ip로 시작하는 태그에 대한 할당을 나열합니다. Mapped_Driver 열에 있는 pooltag.txt 파일의 내용을 사용하는 /g 매개 변수를 사용합니다.

poolmon /iIp* /g

결과 디스플레이에서 Mapped_Driver 열에는 pooltag.txt 파일의 데이터가 포함됩니다.

 Memory:  130616K Avail:   23692K  PageFlts:   146   InRam Krnl: 2108K P: 9532K
 Commit: 187940K Limit: 318628K Peak: 192000K            Pool N: 8372K P:13384K
 System pool information
 Tag  Type     Allocs            Frees            Diff   Bytes      Per Alloc  Mapped_Driver

 IpEQ Nonp          1 (   0)         0 (   0)        1    1808 (     0)   1808 [ipsec][ipsec.sys    -  event queue]
 IpFI Nonp         26 (   0)         0 (   0)       26    7408 (     0)    284 [ipsec][ipsec.sys    -  Filter blocks]
 IpHP Nonp          1 (   0)         1 (   0)        0       0 (     0)      0 [ipsec.sys    - IP Security]
 IpIO Nonp          1 (   0)         1 (   0)        0       0 (     0)      0 [ipsec]
 IpLA Nonp          1 (   0)         0 (   0)        1     248 (     0)    248 [ipsec][ipsec.sys    -  lookaside lists]
 IpSH Nonp          1 (   0)         1 (   0)        0       0 (     0)      0 [ipsec.sys    - IP Security]
 IpSI Nonp       1027 (   0)         0 (   0)     1027   53272 (     0)     51 [ipsec][ipsec.sys    - initial allcoations]
 IpTI Nonp          3 (   0)         0 (   0)        3    5400 (     0)   1800 [ipsec][ipsec.sys    -  timers]

예제 3: 메모리 누수 감지

이 예제에서는 PoolMon을 사용하여 메모리 누수 감지 절차를 제안합니다.

  1. 매개 변수 /p /p(페이징된 풀에서 할당만 표시) 및 /b(바이트 수 기준으로 정렬)를 사용하여 PoolMon을 시작합니다.

    poolmon /p /p /b
    
  2. PoolMon이 몇 시간 동안 실행되도록 합니다. PoolMon을 시작하면 데이터가 변경되므로 데이터를 신뢰할 수 있기 전에 안정적인 상태를 되찾아야 합니다.

  3. PoolMon에서 생성된 정보를 스크린샷으로 저장하거나 명령 창에서 복사하여 메모장에 붙여넣습니다.

  4. PoolMon으로 돌아가서 p 키를 두 번 눌러 페이지가 없는 풀의 할당만 표시합니다.

  5. 3단계와 4단계를 반시간마다 2시간 이상 반복하여 페이징 풀과 비페이지 풀 사이를 전환하면 매번 표시됩니다.

  6. 데이터 수집이 완료되면 각 태그에 대한 Diff(할당 작업에서 자유 연산을 뺀 값) 및 바이트(할당된 바이트 수에서 해제된 바이트 수를 뺀 값)를 검사하고 지속적으로 증가하는 값을 확인합니다.

  7. 그런 다음, PoolMon을 중지하고 몇 시간 동안 기다린 다음 PoolMon을 다시 시작합니다.

  8. 증가된 할당을 검사하고 바이트가 해제되었는지 여부를 확인합니다. 가능한 원인은 아직 해제되지 않았거나 크기가 계속 증가한 할당입니다.

예제 4: 풀 메모리 누수 검사

다음 예제에서는 PoolMon을 사용하여 의심되는 프린터 드라이버에서 풀 메모리 누수 조사를 보여 줍니다. 이 예제에서 PoolMon은 Windows에서 Dsrd 태그를 사용하여 메모리 할당에 대해 수집하는 데이터를 표시합니다.

일부 프린터 드라이버는 GDI(그래픽 디바이스 인터페이스) 개체 및 관련 메모리를 할당할 때 Drsd 태그를 할당합니다. 프린터 드라이버에 개체 누수가 있는 경우 Drsd 태그와 함께 할당된 메모리도 누수됩니다.

참고 이 예제의 단계를 실행하기 전에 사용 중인 프린터가 완료될 때까지 중단되지 않도록 합니다. 그렇지 않으면 결과가 잘못되었을 수 있습니다.

명령줄에서 다음을 입력합니다.

poolmon /iDrsd

이 명령은 Drsd 태그를 사용하여 할당 정보를 표시하도록 PoolMon에 지시합니다. (풀 태그는 대/소문자를 구분하므로 표시된 대로 명령을 정확하게 입력해야 합니다.)

Diff 및 바이트 열에 값을 기록합니다. 다음 샘플 디스플레이에서 Diff 값은 21이고 바이트 수는 17472입니다.

Memory:  130480K Avail:   91856K  PageFlts:  1220   InRam Krnl: 2484K P: 7988K
Commit:  30104K Limit: 248432K Peak:  34028K            Pool N: 2224K P: 8004K
Tag  Type        Allocs           Frees           Diff  Bytes           Per Alloc

Drsd Paged       560 ( 177)       539 ( 171)       21   17472 (  4992)    832 

프린터로 작업을 보내고 Windows가 정상으로 돌아갈 때까지 잠시 기다린 다음 Diff 및 바이트 열의 값을 기록합니다.

Memory:  130480K Avail:   91808K  PageFlts:  1240   InRam Krnl: 2488K P: 7996K
Commit:  30152K Limit: 248432K Peak:  34052K            Pool N: 2224K P: 8012K
Tag  Type        Allocs           Frees           Diff  Bytes          Per Alloc

Drsd Paged       737 (   0)       710 (   0)       27   22464 (     0)    832  

프린터 드라이버의 메모리 관리가 제대로 작동하는 경우 Diff 값은 인쇄 후 원래 값 21로 돌아가야 합니다. 그러나 앞의 출력에서 알 수 있듯이 Diff 값은 27로 상승하고 바이트 수는 22464로 증가했습니다. 초기 출력과 후속 출력의 차이는 총 4992바이트인 6개의 Drsd 블록이 인쇄 중에 유출되었음을 의미합니다.

자세한 내용

유출된 드라이버를 식별했다고 생각되는 경우 Microsoft 지원 웹 사이트로 이동하여 기술 자료에서 관련 문서를 검색하거나 타사 드라이버인 경우 공급업체에 문의하세요.

예제 5: 터미널 서버 세션 모니터링

이 예제에서는 터미널 서비스 세션 풀에서 할당을 표시하는 여러 가지 방법을 보여 줍니다. /s 명령줄 매개 변수 및 s, TSSessionIDi 실행 매개 변수의 사용을 보여 줍니다.

다음 명령은 모든 터미널 서비스 세션 풀의 할당을 표시합니다. 이 예제에서는 터미널 서버로 구성된 로컬 컴퓨터가 세션을 호스팅하고 클라이언트 컴퓨터는 원격 데스크톱 기능을 사용하여 호스트에 연결합니다.

poolmon /s

이에 대한 응답으로 PoolMon은 모든 세션 풀의 할당을 표시합니다. 헤더에 "모든 세션 풀 정보" 제목을 적어 둡니다.

Memory:  523572K Avail:  233036K  PageFlts:   344   InRam Krnl: 1828K P:18380K
Commit: 193632K Limit:1279764K Peak: 987356K            Pool N:14332K P:18644K
All sessions pool information
 Tag  Type     Allocs            Frees            Diff   Bytes       Per Alloc

 Bmfd Paged       361 (   0)       336 (   0)       25   57832 (     0)   2313
 DDfb Paged        34 (   0)        22 (   0)       12     720 (     0)     60
 Dddp Paged         8 (   0)         6 (   0)        2     272 (     0)    136
 Dh 1 Paged        24 (   0)        24 (   0)        0       0 (     0)      0
 Dh 2 Paged       344 (   0)       344 (   0)        0       0 (     0)      0
 Dvgr Paged         2 (   0)         2 (   0)        0       0 (     0)      0
 GDev Paged       108 (   0)       102 (   0)        6   20272 (     0)   3378
 GFil Paged        29 (   0)        27 (   0)        2     160 (     0)     80
 GPal Paged        11 (   0)         8 (   0)        3     816 (     0)    272
 GTmp Paged     88876 (   1)     88876 (   1)        0       0 (     0)      0
 GUma Paged         2 (   0)         2 (   0)        0       0 (     0)      0
 Galp Paged      3250 (   0)      3250 (   0)        0       0 (     0)      0
 Gbaf Paged      9829 (   0)      9801 (   0)       28   19712 (     0)    704
 Gcac Paged      3761 (   0)      3706 (   0)       55  288968 (     0)   5253
 Gcsl Paged         1 (   0)         0 (   0)        1     488 (     0)    488
 Gdbr Paged      6277 (   0)      6271 (   0)        6    1872 (     0)    312
 ...

특정 세션 풀에서 할당을 보려면 다음 명령과 같이 /s 매개 변수 바로 다음에 세션 ID를 입력합니다. 이 명령은 터미널 서비스 세션 0에 대한 세션 풀 할당을 표시합니다.

poolmon /s0

이에 대한 응답으로 PoolMon은 터미널 서비스 세션 0에 대한 세션 풀의 할당을 표시합니다. 헤더에 "세션 0 풀 정보" 제목을 적어 둡니다.

Memory:  523572K Avail:  233024K  PageFlts:   525   InRam Krnl: 1828K P:18384K
 Commit: 193760K Limit:1279764K Peak: 987356K            Pool N:14340K P:18644K
 Session 0 pool information
 Tag  Type     Allocs            Frees            Diff   Bytes       Per Alloc

 Bmfd Paged       361 (   0)       336 (   0)       25   57832 (     0)   2313
 DDfb Paged        34 (   0)        22 (   0)       12     720 (     0)     60
 Dddp Paged         8 (   0)         6 (   0)        2     272 (     0)    136
 Dh 1 Paged        24 (   0)        24 (   0)        0       0 (     0)      0
 Dh 2 Paged       344 (   0)       344 (   0)        0       0 (     0)      0
 Dvgr Paged         2 (   0)         2 (   0)        0       0 (     0)      0
 GDev Paged       108 (   0)       102 (   0)        6   20272 (     0)   3378
 GFil Paged        29 (   0)        27 (   0)        2     160 (     0)     80
 GPal Paged        11 (   0)         8 (   0)        3     816 (     0)    272
 GTmp Paged     89079 (  99)     89079 (  99)        0       0 (     0)      0
 GUma Paged         2 (   0)         2 (   0)        0       0 (     0)      0
 Galp Paged      3250 (   0)      3250 (   0)        0       0 (     0)      0
 Gbaf Paged      9830 (   0)      9802 (   0)       28   19712 (     0)    704
 Gcac Paged      3762 (   0)      3707 (   0)       55  283632 (     0)   5156
 Gcsl Paged         1 (   0)         0 (   0)        1     488 (     0)    488
 Gdbr Paged      6280 (   0)      6274 (   0)        6    1872 (     0)    312
 ...

세션 풀에서 메모리를 할당하는 드라이버 및 구성 요소를 확인하려면 다음 명령과 같이 /g 매개 변수를 추가합니다. /g 매개 변수는 각 태그를 할당하는 Windows 구성 요소 및 드라이버를 나열하는 Mapped_Driver 열을 추가합니다.

poolmon /s0 /g

Memory:  523572K Avail:  235876K  PageFlts:    43   InRam Krnl: 1900K P:18860K
Commit: 185040K Limit:1279764K Peak: 987356K            Pool N:14684K P:19124K
Session 0 pool information
Tag  Type     Allocs            Frees            Diff   Bytes      Per Alloc  Mapped_Driver

Bmfd Paged       421 (   0)       396 (   0)       25   57832 (     0)   2313 [Font related stuff]
DDfb Paged        34 (   0)        22 (   0)       12     720 (     0)     60 Unknown Driver
Dddp Paged        11 (   0)         6 (   0)        5     392 (     0)     78 Unknown Driver
Dh 1 Paged        37 (   0)        35 (   0)        2     224 (     0)    112 Unknown Driver
Dh 2 Paged       367 (   0)       364 (   0)        3     912 (     0)    304 Unknown Driver
Dvgr Paged         2 (   0)         2 (   0)        0       0 (     0)      0 [vga for risc video driver]
GDev Paged       119 (   0)       113 (   0)        6   20272 (     0)   3378 [Gdi pdev]
GFil Paged        29 (   0)        27 (   0)        2     160 (     0)     80 [Gdi engine descriptor list]
GPal Paged        11 (   0)         8 (   0)        3     816 (     0)    272 [Gdi Objects]
GTmp Paged     98626 (   1)     98626 (   1)        0       0 (     0)      0 [Gdi Objects]
GUma Paged         2 (   0)         2 (   0)        0       0 (     0)      0 [Gdi Objects]
Galp Paged      3250 (   0)      3250 (   0)        0       0 (     0)      0 [Gdi Objects]
Gbaf Paged     10331 (   0)     10305 (   0)       26   18304 (     0)    704 [Gdi Objects]
Gcac Paged      4722 (   0)      4666 (   0)       56  305400 (     0)   5453 [Gdi glyph cache]
Gcsl Paged         1 (   0)         0 (   0)        1     488 (     0)    488 [Gdi string resource script names]
Gdbr Paged      6972 (   0)      6965 (   0)        7    2184 (     0)    312 [Gdi driver brush realization]

PoolMon이 실행되는 동안 터미널 서비스 세션 풀 디스플레이를 구성할 수도 있습니다. 다음 표에서는 일련의 실행 중인 명령(형식이 지정된 순서 및 결과 PoolMon 표시)을 보여 줍니다.

계열은 PoolMon을 시작하는 명령으로 시작합니다. PoolMon이 실행되는 동안 다른 모든 매개 변수가 입력됩니다.

poolmon
Key 결과 Description

s

모든 세션 풀을 표시합니다.

s

시스템 풀을 표시합니다.

s 매개 변수는 시스템 풀과 터미널 서비스 세션 풀 간의 표시를 전환합니다.

0

세션 0 풀을 표시합니다.

시스템 풀을 표시하는 동안 세션 ID를 입력할 수 있습니다.

7

세션 7 풀을 표시합니다.

a

할당 수별로 정렬된 세션 7에 대한 풀 할당을 표시합니다.

모든 표준 실행 매개 변수는 세션 풀 디스플레이에 유효합니다.

0

세션 0에 대한 할당을 할당 수별로 정렬하여 표시합니다.

세션 및 정렬 옵션은 변경될 때까지 유지됩니다.

s

시스템 풀을 표시합니다.

s

세션 0에 대한 할당을 할당 수별로 정렬하여 표시합니다.

세션 옵션은 유지됩니다.

10엔터

세션 1 할당을 표시한 다음 세션 0 할당을 표시합니다.

i가 없으면 세션 ID 0~9만 입력할 수 있습니다.

i

터미널 서버 세션 ID를 묻는 메시지를 표시합니다.

10

세션 10 할당을 표시합니다.

i

터미널 서버 세션 ID를 묻는 메시지를 표시합니다.

모든 세션 풀을 표시하려면 i 키를 누른 다음 Enter 키를 누릅니다.

Enter

모든 세션 풀을 표시합니다.

터미널 서버로 구성된 시스템만 세션 풀에서 메모리를 할당합니다. PoolMon을 사용하여 터미널 서버가 아닌 컴퓨터에 세션 풀을 표시하거나 Windows에 없는 세션 ID를 입력하는 경우 PoolMon은 할당을 표시하지 않습니다. 대신 일반 메모리 데이터가 있는 제목만 표시합니다.

다음 명령은 모든 터미널 서비스 세션 풀의 할당을 표시합니다.

poolmon /s

다음 그림에서는 터미널 서버로 구성할 수 없는 Windows XP를 실행하는 컴퓨터에 /s 명령이 제출된 경우 발생하는 PoolMon 디스플레이를 보여 봅니다.

 Memory:  260620K Avail:   44956K  PageFlts:   308   InRam Krnl: 2744K P:20444K
 Commit: 185452K Limit: 640872K Peak: 192472K            Pool N: 8112K P:20648K
 All sessions pool information
 Tag  Type     Allocs            Frees            Diff   Bytes       Per Alloc