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 パラメーターを含めることができます。 次のコマンドは、タグが Audで始まり、Cc で始まる4 文字のタグを持つ割り当てを表示します。ただし、 CcBc タグを使用した割り当てを除きます。
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 と同じ場所にコピーすることもできます。 これにより、このような使い方が可能になります。
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 を使用してメモリ リークを検出する手順を示します。
パラメーター /p /p (ページ プールからの割り当てのみを表示) と /b (バイト数で並べ替える) を使用して PoolMon を開始します。
poolmon /p /p /b
PoolMon を数時間実行します。 PoolMon を開始するとデータが変更されるため、データの信頼性を確保する前に定常状態に戻す必要があります。
PoolMon によって生成された情報をスクリーン ショットとして保存するか、コマンド ウィンドウからコピーしてメモ帳に貼り付けます。
PoolMon に戻り、Pキーを2 回押すと、非ページ プールからの割り当てのみが表示されます。
手順 3 と 4 を約 30 分ごとに最低 2 時間繰り返し、ページ プールと非ページ プールの表示を毎回切り替えます。
データ収集が完了したら、各タグの Diff (割り当て操作から空き操作を除く) とバイト (割り当てられたバイト数から解放されたバイト数を引いたバイト数) の値を調べて、継続的に増加する値に注意してください。
次に、PoolMon を停止し、数時間待ってから、PoolMon を再起動します。
増加していた割り当てを調べて、バイトが解放されたかどうかを判断します。 原因として考えられるのは、まだ解放されていない割り当て、またはサイズの増加が続いている割り当てです。
例 4: プール のメモリ リークの調査
次の例は、PoolMon を使用して、疑わしいプリンター ドライバーからのプール メモリ リークを調査する方法を示しています。 この例では、PoolMon は、Windows が Dsrd タグを使用してメモリ割り当てに関して収集するデータを表示します。
一部のプリンター ドライバーは、グラフィックス デバイス インターフェイス (GDI) オブジェクトと関連するメモリを割り当てる際に、Drsd タグを割り当てます。 プリンター ドライバーにオブジェクト リークがある場合、Drsd タグで割り当てられたメモリもリークします。
注 この 例の手順を実行する前に、使用しているプリンターが完了するまで中断されないことを確認します。 そうでない場合、結果が無効になる可能性があります。
コマンド ラインに次のように入力します。
poolmon /iDrsd
このコマンドは、Drsd タグを使用して割り当ての情報を表示するように PoolMon に指示します。 (プール タグでは大文字と小文字が区別されるため、次のようにコマンドを正確に入力してください。)
Diff 列と Bytes 列に値を記録します。 次の表示例では、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 列と Bytes 列の値を記録します。
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 に増加しました。 最初の出力とその後の出力の違いは、6 つの Drsd ブロック (合計 4992 バイト) が印刷中にリークしたことを意味します。
詳細情報
リークしているドライバーを特定したと思われる場合は、Microsoft サポート Web サイトにアクセスし、ナレッジベースで関連する記事を検索するか、サード パーティ製ドライバーの場合はベンダーにお問い合わせください。
例 5: ターミナル サーバー セッションの監視
この例では、ターミナル サービス セッション プールからの割り当てを表示する方法をいくつか示します。 これは、 /sコマンド ライン パラメーターと、パラメーターを実行している s、TSSessionID 、および i の使用方法を示しています。
次のコマンドは、すべてのターミナル サービス セッション プールからの割り当てを表示します。 この例では、ターミナル サーバーとして構成されているローカル コンピューターがセッションをホストしており、クライアント コンピューターはリモート デスクトップ機能を使用してホストに接続しています。
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
キー | 結果 | 説明 |
---|---|---|
s |
すべてのセッション プールを表示します。 |
|
s |
システム プールを表示します。 |
s パラメーターは、システム プールとターミナル サービス セッション プール間の表示を切り替えます。 |
0 |
セッション 0 プールを表示します。 |
システム プールの表示中にセッション ID を入力できます。 |
7 |
セッション 7 プールを表示します。 |
|
a |
セッション 7 のプール割り当てを割り当て数で並べ替え、表示します。 |
すべての標準実行パラメーターは、セッション プールの表示に対して有効です。 |
0 |
セッション 0 のプール割り当てを割り当て数で並べ替え、表示します。 |
セッションと並べ替えのオプションは、変更されるまで保持されます。 |
s |
システム プールを表示します。 |
|
s |
セッション 0 のプール割り当てを割り当て数で並べ替え、表示します。 |
セッション オプションは保持されます。 |
10ENTER |
セッション 1 の割り当てを表示し、セッション 0 の割り当てを表示します。 |
iがない場合は、セッション ID 0 から 9 のみを入力できます。 |
i |
ターミナル サーバー セッション ID の入力を求めるメッセージが表示されます。 |
|
"10" |
セッション 10 の割り当てを表示します。 |
|
i |
ターミナル サーバー セッション ID の入力を求めるメッセージが表示されます。 |
すべてのセッション プールを表示するには、 I キーを押してから Enter キーを押します。 |
Enter |
すべてのセッション プールを表示します。 |
ターミナル サーバーとして構成されたシステムのみが、セッション プールからメモリを割り当てます。 PoolMon を使用して、ターミナル サーバーではないコンピューターにセッション プールを表示する場合、または Windows に存在しないセッション ID を入力した場合、PoolMon は割り当てを表示しません。 代わりに、一般的なメモリ データを含む見出しのみが表示されます。
次のコマンドは、すべてのターミナル サービス セッション プールからの割り当てを表示します。
poolmon /s
次の図は、/s コマンドがターミナル サーバーとして構成できなかった Windows XP を実行しているコンピューターに送信された場合に発生する 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