!heap

!heap 拡張機能は、ヒープ使用量情報の表示、ヒープ マネージャー内のブレークポイントの制御、リークしたヒープ ブロックの検出、ヒープ ブロックの検索、ページ ヒープ情報の表示を行います。

この拡張機能はセグメント ヒープと NT ヒープをサポートします。 すべてのヒープとそのタイプをリストするには、パラメータなしで !heap を使用します。

!heap [HeapOptions] [ValidationOptions] [Heap] 
!heap -b [{alloc|realloc|free} [Tag]] [Heap | BreakAddress] 
!heap -B {alloc|realloc|free} [Heap | BreakAddress] 
!heap -l 
!heap -s [SummaryOptions] [StatHeapAddress] 
!heap -i HeapAddress
!heap -x [-v] Address 
!heap -p [PageHeapOptions] 
!heap -srch [Size] Pattern
!heap -flt FilterOptions
!heap -stat [-h Handle [-grp GroupBy [MaxDisplay]]]
!heap [-p] -?
!heap -triage [Handle | Address] 

セグメントおよびNTヒープパラメータ

これらのパラメーターは、セグメント ヒープおよび NT ヒープで機能します。

-s
概要情報が要求されていることを指定します。 SummaryOptionsStatHeapAddress を省略した場合、現在のプロセスに関連付けられているすべてのヒープの概要情報が表示されます。

概要オプション
次のオプションを任意に組み合わせて使用できます。 SummaryOptions では大文字と小文字が区別されません。 「!heap -s -?」と入力します。 追加情報については。

オプション 効果

-v

すべてのデータブロックを検証します。

-bBucketSize

バケットのサイズを指定します。 デフォルトは 1024 ビットです。

-dDumpBlockSize

バケットのサイズを指定します。

-a

すべてのヒープ ブロックをダンプします。

-c

各ブロックの内容を表示することを指定します。

-triage [Handle|Address]
デバッガーがプロセスのヒープ内の障害を自動的に検索します。 ヒープ ハンドルが引数として指定されている場合、そのヒープが検査されます。 それ以外の場合は、指定されたアドレスを含むヒープがすべてのヒープから検索され、見つかった場合は検査されます。 使用する -triage を使用することが、低断片化ヒープ (LFH) の破損を検証する唯一の方法です。

-x [-v]
デバッガーは、指定されたアドレスを含むヒープ ブロックを検索します。 -v を追加すると、コマンドは現在のプロセスの仮想メモリ空間全体でこのヒープ ブロックへのポインターを検索します。

-l
デバッガにリークしたヒープ ブロックを検出させます。

-iAddress-hHeapAddress
指定したヒープに関する情報を表示します Heap

住所
検索するアドレスを指定します。

-?
デバッガーコマンドウィンドウで、この拡張機能の簡単なヘルプテキストを表示します。 !heap -? を使用します。 一般的なヘルプについては !heap -p -? ページ ヒープのヘルプについては。

NT ヒープパラメータ

これらのパラメータは、NT ヒープでのみ機能します。

ヒープオプション
次のオプションを任意に組み合わせて使用できます。 その HeapOptions の値では大文字と小文字が区別されます。

オプション 効果

-v

デバッガーに指定されたヒープを検証させます。

このオプションは、低断片化ヒープ (LFH) の破損を検出しません。 を使用してください -triage 代わりに 。

-a

指定されたヒープのすべての情報が表示に含まれます。 この場合、サイズはヒープ粒度に切り上げられます。 (ランニング中 !heap とともに -a オプションは 3 つのオプションを指定して実行するのと同じです -h -f -m, これには長い時間がかかる場合があります。)

-h

指定されたヒープの非 LFH エントリをすべて表示に含めます。

-hl

LFH エントリを含む、指定されたヒープのすべてのエントリが表示に含まれます。

-f

指定されたヒープのすべての空きリスト エントリが表示に含まれます。

-m

指定されたヒープのすべてのセグメント エントリが表示に含まれます。

-t

指定したヒープのタグ情報を表示に含めます。

-T

指定されたヒープの疑似タグ エントリを表示に含めます。

-g

表示にグローバル タグ情報が含まれるようにします。 グローバル タグは、タグなしの各割り当てに関連付けられます。

-s

指定したヒープの概要情報を表示に含めます。

-k

(x86 ベースのターゲットのみ) 各エントリに関連付けられたスタック バックトレースを表示に含めます。

検証オプション
次のオプションのいずれか 1 つを指定できます。 その ValidationOptions では大文字と小文字が区別されます。

オプション 効果

-D

指定されたヒープの validate-on-call を無効にします。

-E

指定されたヒープの validate-on-call を有効にします。

-d

指定されたヒープのヒープチェックを無効にします。

-e

指定されたヒープのヒープ チェックを有効にします。

-iHeapAddressorHeapAddress
指定したヒープに関する情報を表示します Heap

ブレークアドレス
ブレークポイントを設定または削除するブロックのアドレスを指定します。

-b
デバッガーがヒープ マネージャーに条件付きブレークポイントを作成します。 その -b オプションの後に続けることができ alloc, realloc, or フリー; これは、ブレークポイントがメモリの割り当て、再割り当て、または解放によってアクティブ化されるかどうかを指定します。 もし BreakAddress を使用してブロックのアドレスを指定する場合、ブレークポイントの種類は省略できます。 もし Heap はヒープ アドレスまたはヒープ インデックスを指定するために使用されます。ヒープ アドレスまたはヒープ インデックスを指定するために、タイプだけでなく、 タグ パラメーター。

Tag
ヒープ内のタグ名を指定します。

-B
デバッガーがヒープ マネージャーから条件付きブレークポイントを削除します。 ブレークポイントの種類 (alloc, realloc, or free) を指定する必要があり、で使用されるものと同じでなければなりません -b というオプション。

統計ヒープアドレス
ヒープのアドレスを指定します。 これが 0 であるか省略された場合、現在のプロセスに関連付けられているすべてのヒープが表示されます。

-p
ページ ヒープ情報が要求されていることを指定します。 これを PageHeapOptions なしで使用すると、すべてのページ ヒープが表示されます。

ページヒープオプション
次のオプションのいずれか 1 つを指定できます。 PageHeapOptions では大文字と小文字が区別されます。 オプションが指定されていない場合は、可能なすべてのページ ヒープ ハンドルが表示されます。

オプション 効果

-hHandle

デバッガーに、ハンドル Handleを持つページ ヒープに関する詳細情報を表示させます。

-aAddress

デバッガーは、ブロックに アドレスが含まれるページ ヒープを検索します.。 このアドレスがページ ヒープの一部であるかどうか、ブロック内のオフセット、ブロックが割り当てられているか解放されたかなど、このアドレスがフルページ ヒープ ブロックにどのように関連するかについての完全な詳細が含まれます。 スタック トレースは利用可能な場合には常に含まれます。 このオプションを使用すると、サイズはヒープ割り当て粒度の倍数で表示されます。

-t[c|s] [Traces]

デバッガーに、ヘビー ヒープ ユーザーの収集されたトレースを表示させます。 Traces は、表示するトレースの数を指定します。 デフォルトは 4 です。 指定した数より多くのトレースがある場合は、最も古いトレースが表示されます。 もし -t または -tc が使用されている場合、トレースはカウントの使用状況によってソートされます。 -ts を使用すると、トレースはサイズによってソートされます。 (その -tc そして -ts オプションは Windows XP でのみサポートされています; その -t このオプションは、Windows XP およびそれ以前のバージョンの Windows でのみサポートされています。)

-fi [Traces]

デバッガーに最新のフォールト挿入トレースを表示させます。 トレース は表示する量を指定します。 デフォルトは 4 です。

-全て

デバッガーにすべてのページ ヒープに関する詳細情報を表示させます。

-?

デバッガーに、ヒープ ブロックの図を含むページ ヒープ ヘルプを表示させます。 (これらの図は、次の「備考」セクションにも記載されています。)

!heap -p 拡張コマンドを使用する前に、ターゲット プロセスに対してページ ヒープを有効にする必要があります。 詳細については、次の「備考」セクションを参照してください。

srch-
指定されたパターンのすべてのヒープをスキャンします。

パターン
検索するパターンを指定します。

[サイズ]
次のオプションのいずれか 1 つを指定できます。 模様のサイズを指定します。 「-」は必須です。

オプション 効果

-b

パターンのサイズは 1 バイトです。

-w

パターンのサイズは 1 ワードです。

-d

パターンのサイズは 1 DWORD です。

-q

パターンのサイズは 1 QWORD です。

上記のいずれも指定されていない場合、パターンはマシン ポインターと同じサイズであるとみなされます。

-flt
指定されたサイズまたはサイズ範囲のヒープのみが含まれるように表示を制限します。

フィルターオプション
次のオプションのいずれか 1 つを指定できます。 FilterOptions では大文字と小文字が区別されます。

オプション 効果

sSize

指定したサイズのヒープのみが含まれるように表示を制限します。

rSizeMinSizeMax

指定されたサイズ範囲内のヒープのみが含まれるように表示を制限します。

-stat
指定されたヒープの使用量統計を表示します。

-hHandle
にあるヒープだけの使用統計を取る Handle が表示されます。 Handle が 0 または省略された場合、すべてのヒープの使用量統計が表示されます。

-grpGroupBy
で指定されたとおりに表示を並べ替えます GroupByGroupBy のオプションを次の表に示します。

オプション 効果

A

割り当てサイズに応じた使用量統計を表示します。

B

ブロック数に応じた使用量統計を表示します。

S

各割り当ての合計サイズに応じた使用量統計を表示します。

マックスディスプレイ
出力を MaxDisplay 行数のみに制限します。

DLL

Windows XP以降

Ext.dll Ext.dll

追加情報

ヒープについては、次のリソースを参照してください。

本: Mark Russinovich と David Solomon による Microsoft Windows Internals。

例 11: ページ ヒープ検証を有効にする

例 12: ページ ヒープ検証を使用してバグを見つける

ヒープ メモリ プロセス ロガーの使用方法については、 例 11 を参照してください。プライベート トレース セッションの開始

解説

この拡張コマンドを使用して、さまざまなタスクを実行できます。

標準の !heap コマンドは、現在のプロセスのヒープ情報を表示するために使用されます。 (これはユーザーモードのプロセスにのみ使用してください。 !pool 拡張コマンドはシステム プロセスに使用する必要があります。)

!heap -b および !heap -B コマンドは、ヒープ マネージャーで条件付きブレークポイントを作成および削除するために使用されます。

!heap -l コマンドは、リークしたヒープ ブロックを検出します。 ガベージ コレクター アルゴリズムを使用して、プロセス アドレス空間のどこにも参照されていないヒープからすべてのビジー ブロックを検出します。 大規模なアプリケーションの場合、完了までに数分かかる場合があります。 このコマンドは、Windows XP 以降のバージョンの Windows でのみ使用できます。

!heap -x コマンドは、指定されたアドレスを含むヒープ ブロックを検索します。 -v オプションが使用されている場合、このコマンドはさらに、現在のプロセスの仮想メモリ空間全体でこのヒープ ブロックへのポインターを検索します。 このコマンドは、Windows XP 以降のバージョンの Windows でのみ使用できます。

!heap -p コマンドは、さまざまな形式のページ ヒープ情報を表示します。 !heap -p を使用する前に、ターゲット プロセスのページ ヒープを有効にする必要があります。 これは、Global Flags (gflags.exe) ユーティリティを通じて行われます。 これを行うには、ユーティリティを起動し、ターゲット アプリケーションの名前を イメージファイル名 テキストボックス、選択 イメージファイルオプション そして ページ ヒープを有効にする, そして選択します 適用する. あるいは、次のように入力して、コマンド プロンプト ウィンドウから Global Flags ユーティリティを起動することもできます gflags /ixxx.exe+hpa, どこ xxx.exe ターゲット アプリケーションの名前です。

!heap -p -t[c|s] コマンドは、Windows XP 以降ではサポートされません。 デバッガー パッケージに付属の UMDH ツールを使用すると、同様の結果が得られます。

!heap -srch コマンドは、特定の指定されたパターンを含むヒープ エントリを表示します。

!heap -flt コマンドは、指定されたサイズのヒープ割り当てのみに表示を制限します。

その !heap -stat コマンドはヒープ使用量の統計を表示します。

標準の !heap コマンドの例を次に示します。

0:000> !ntsdexts.heap -a
Index   Address  Name      Debugging options enabled
  1:   00250000 
    Segment at 00250000 to 00350000 (00056000 bytes committed)
    Flags:               50000062
    ForceFlags:          40000060
    Granularity:         8 bytes
    Segment Reserve:     00100000
    Segment Commit:      00004000
    DeCommit Block Thres:00000400
    DeCommit Total Thres:00002000
    Total Free Size:     000003be
    Max. Allocation Size:7ffddfff
    Lock Variable at:    00250b54
    Next TagIndex:       0012
    Maximum TagIndex:    07ff
    Tag Entries:         00350000
    PsuedoTag Entries:   00250548
    Virtual Alloc List:  00250050
    UCR FreeList:        002504d8
    128-bit bitmap of free lists
    FreeList Usage:      00000014 00000000 00000000 00000000
              Free    Free
              List    List
#       Head      Blink      Flink
    FreeList[ 00 ] at 002500b8: 002a4378 . 002a4378
                                0x02 - HEAP_ENTRY_EXTRA_PRESENT
                                0x04 - HEAP_ENTRY_FILL_PATTERN
        Entry     Prev    Cur   0x10 - HEAP_ENTRY_LAST_ENTRY

Address   Size    Size  flags
002a4370: 00098 . 01c90 [14] - free
    FreeList[ 02 ] at 002500c8: 0025cb30 . 002527b8
002527b0: 00058 . 00010 [04] - free
0025cb28: 00088 . 00010 [04] - free
    FreeList[ 04 ] at 002500d8: 00269a08 . 0026e530
0026e528: 00038 . 00020 [04] - free
0026a4d0: 00038 . 00020 [06] - free
0026f9b8: 00038 . 00020 [04] - free
0025cda0: 00030 . 00020 [06] - free
00272660: 00038 . 00020 [04] - free
0026ab60: 00038 . 00020 [06] - free
00269f20: 00038 . 00020 [06] - free
00299818: 00038 . 00020 [04] - free
0026c028: 00038 . 00020 [06] - free
00269a00: 00038 . 00020 [46] - free
 
    Segment00 at 00250b90:
Flags:           00000000
Base:            00250000
First Entry:     00250bc8
Last Entry:      00350000
Total Pages:     00000080
Total UnCommit:  00000055
Largest UnCommit:000aa000
UnCommitted Ranges: (1)
    002a6000: 000aa000

    Heap entries for Segment00 in Heap 250000
                        0x01 - HEAP_ENTRY_BUSY            
                        0x02 - HEAP_ENTRY_EXTRA_PRESENT   
                        0x04 - HEAP_ENTRY_FILL_PATTERN    
                        0x08 - HEAP_ENTRY_VIRTUAL_ALLOC   
                        0x10 - HEAP_ENTRY_LAST_ENTRY      
                        0x20 - HEAP_ENTRY_SETTABLE_FLAG1  
                        0x40 - HEAP_ENTRY_SETTABLE_FLAG2  
Entry     Prev    Cur   0x80 - HEAP_ENTRY_SETTABLE_FLAG3  

Address   Size    Size  flags       (Bytes used)    (Tag name)
00250000: 00000 . 00b90 [01] - busy (b90)
00250b90: 00b90 . 00038 [01] - busy (38) 
00250bc8: 00038 . 00040 [07] - busy (24), tail fill (NTDLL!LDR Database)
00250c08: 00040 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00250c68: 00060 . 00028 [07] - busy (10), tail fill (NTDLL!LDR Database)
00250c90: 00028 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00250cf0: 00060 . 00050 [07] - busy (38), tail fill (Objects=  80)
00250d40: 00050 . 00048 [07] - busy (2e), tail fill (NTDLL!LDR Database)
00250d88: 00048 . 00c10 [07] - busy (bf4), tail fill (Objects>1024)
00251998: 00c10 . 00030 [07] - busy (12), tail fill (NTDLL!LDR Database)
...
002525c0: 00030 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00252620: 00060 . 00050 [07] - busy (38), tail fill (NTDLL!LDR Database)
00252670: 00050 . 00040 [07] - busy (22), tail fill (NTDLL!CSRSS Client)
002526b0: 00040 . 00040 [07] - busy (24), tail fill (Objects=  64)
002526f0: 00040 . 00040 [07] - busy (24), tail fill (Objects=  64)
00252730: 00040 . 00028 [07] - busy (10), tail fill (Objects=  40)
00252758: 00028 . 00058 [07] - busy (3c), tail fill (Objects=  88)
002527b0: 00058 . 00010 [04] free fill
002527c0: 00010 . 00058 [07] - busy (3c), tail fill (NTDLL!LDR Database)
00252818: 00058 . 002d0 [07] - busy (2b8), tail fill (Objects= 720)
00252ae8: 002d0 . 00330 [07] - busy (314), tail fill (Objects= 816)
00252e18: 00330 . 00330 [07] - busy (314), tail fill (Objects= 816)
00253148: 00330 . 002a8 [07] - busy (28c), tail fill (NTDLL!LocalAtom)
002533f0: 002a8 . 00030 [07] - busy (18), tail fill (NTDLL!LocalAtom)
00253420: 00030 . 00030 [07] - busy (18), tail fill (NTDLL!LocalAtom)
00253450: 00030 . 00098 [07] - busy (7c), tail fill (BASEDLL!LMEM)
002534e8: 00098 . 00060 [07] - busy (44), tail fill (BASEDLL!TMP)
00253548: 00060 . 00020 [07] - busy (1), tail fill (Objects=  32)
00253568: 00020 . 00028 [07] - busy (10), tail fill (Objects=  40)
00253590: 00028 . 00030 [07] - busy (16), tail fill (Objects=  48)
...
0025ccb8: 00038 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
0025cd18: 00060 . 00058 [07] - busy (3c), tail fill (NTDLL!LDR Database)
0025cd70: 00058 . 00030 [07] - busy (18), tail fill (NTDLL!LDR Database)
0025cda0: 00030 . 00020 [06] free fill (NTDLL!Temporary)
0025cdc0: 00020 . 00258 [07] - busy (23c), tail fill (Objects= 600)
0025d018: 00258 . 01018 [07] - busy (1000), tail fill (Objects>1024)
0025e030: 01018 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
...
002a4190: 00028 . 00118 [07] - busy (100), tail fill (BASEDLL!GMEM)
002a42a8: 00118 . 00030 [07] - busy (18), tail fill (Objects=  48)
002a42d8: 00030 . 00098 [07] - busy (7c), tail fill (Objects= 152)
002a4370: 00098 . 01c90 [14] free fill
002a6000:      000aa000      - uncommitted bytes.

以下はその一例です !heap -l コマンド:

1:0:011> !heap -l
1:Heap 00170000
Heap 00280000
Heap 00520000
Heap 00b50000
Heap 00c60000
Heap 01420000
Heap 01550000
Heap 016d0000
Heap 019b0000
Heap 01b40000
Scanning VM ...
## Entry     User      Heap      Segment       Size  PrevSize  Flags

001b2958  001b2960  00170000  00000000        40        18  busy extra
001b9cb0  001b9cb8  00170000  00000000        80       300  busy extra
001ba208  001ba210  00170000  00000000        80        78  busy extra
001cbc90  001cbc98  00170000  00000000        e0        48  busy extra
001cbd70  001cbd78  00170000  00000000        d8        e0  busy extra
001cbe90  001cbe98  00170000  00000000        68        48  busy extra
001cbef8  001cbf00  00170000  00000000        58        68  busy extra
001cc078  001cc080  00170000  00000000        f8       128  busy extra
001cc360  001cc368  00170000  00000000        80        50  busy extra
001cc3e0  001cc3e8  00170000  00000000        58        80  busy extra
001fe550  001fe558  00170000  00000000       150       278  busy extra
001fe6e8  001fe6f0  00170000  00000000        48        48  busy extra
002057a8  002057b0  00170000  00000000        58        58  busy extra
00205800  00205808  00170000  00000000        48        58  busy extra
002058b8  002058c0  00170000  00000000        58        70  busy extra
00205910  00205918  00170000  00000000        48        58  busy extra
00205958  00205960  00170000  00000000        90        48  busy extra
00246970  00246978  00170000  00000000        60        88  busy extra
00251168  00251170  00170000  00000000        78        d0  busy extra user_flag
00527730  00527738  00520000  00000000        40        40  busy extra
00527920  00527928  00520000  00000000        40        80  busy extra
21 leaks detected.

この例のテーブルには、見つかった 21 個のリークすべてが含まれています。

!heap -x コマンドの例を次に示します。

0:011> !heap 002057b8 -x
## Entry     User      Heap      Segment       Size  PrevSize  Flags

002057a8  002057b0  00170000  00170640        58        58  busy extra

!heap -x -v コマンドの例を次に示します。

1:0:011> !heap 002057b8 -x -v
## 1:Entry     User      Heap      Segment       Size  PrevSize  Flags

002057a8  002057b0  00170000  00170640        58        58  busy extra

Search VM for address range 002057a8 - 002057ff : 00205990 (002057d0),

この例では、アドレス 0x00205990 にこのヒープ ブロックへのポインターがあります。

!heap -flt s コマンドの例を次に示します。

0:001>!heap -flt s 0x50

これにより、サイズ 0x50 のすべての割り当てが表示されます。

!heap -flt r コマンドの例を次に示します。

0:001>!heap -flt r 0x50 0x80

これにより、サイズが 0x50 から 0x7F までの各割り当てが表示されます。

次に、 !heap -srch コマンドの例を示します。

0:001> !heap -srch 77176934
    _HEAP @ 00090000
   in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
        00099A48: 0018 : 0005 [01] - 00099A50 (000000B8) - (busy)
          ole32!CALLFRAME_CACHE<INTERFACE_HELPER_CLSID>::`vftable'
    _HEAP @ 00090000
   in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
        00099B58: 0018 : 0005 [01] - 00099B60 (000000B8) - (busy)
          ole32!CALLFRAME_CACHE<INTERFACE_HELPER_CLSID>::`vftable'

ヒープブロックの配置を次の図に示します。

ライト ページ ヒープ ブロック -- 割り当て:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 suffix bytes (filled with 0xA0)    
    |         User allocation (filled with E0 if zeroing not requested) 
    Block header (starts with 0xABCDAAAA and ends with 0xDCBAAAAA) 

ライトページヒープブロック -- 解放されました:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 suffix bytes (filled with 0xA0)    
    |         User allocation (filled with F0 bytes)          
    Block header (starts with 0xABCDAAA9 and ends with 0xDCBAAA9) 

フル ページ ヒープ ブロック -- 割り当てられます:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 suffix bytes (filled with 0xD0)        
    |       User allocation (if zeroing not requested, filled   
            with C0)       
    Block header (starts with 0xABCDBBBB and ends with 0xDCBABBBB) 

ページ全体のヒープ ブロック -- 解放されました:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 suffix bytes (filled with 0xD0)        
    |       User allocation (filled with F0 bytes)            
    Block header (starts with 0xABCDBBA and ends with 0xDCBABBBA) 

ヒープ ブロックやフル ページ ヒープ ブロックの割り当てや解放のスタック トレースを確認するには、次を使用します dt DPH_BLOCK_INFORMATION ヘッダーアドレスに続いて dds ブロックと一緒に StackTrace 分野。