共用方式為


!堆

!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 堆積參數

這些參數適用於 Segment 和 NT 堆積。

-s
指定要求摘要資訊。 如果 省略 SummaryOptionsStatHeapAddress ,則會針對與目前進程相關聯的所有堆積顯示摘要資訊。

SummaryOptions
可以是下列選項的任何組合。 SummaryOptions 不區分大小寫。 輸入 !heap -s -? 如需其他資訊。

選項 影響

-v

驗證所有數據區塊。

-bBucketSize

指定貯體大小。 預設值為1024位。

-dDumpBlockSize

指定貯體大小。

-a

傾印所有堆積區塊。

-c

指定應該顯示每個區塊的內容。

-triage [Handle|Address]
讓調試程式自動搜尋進程堆積中的失敗。 如果堆積句柄指定為自變數,則會檢查該堆積;否則,所有堆積都會搜尋包含指定位址的堆積,如果找到該堆積,則會加以檢查。 使用 -triage 是驗證低片段堆積 (LFH) 損毀的唯一方法。

-x [-v]
讓調試程式搜尋包含指定位址的堆積區塊。 如果已新增 -v,命令會搜尋目前進程的整個虛擬記憶體空間,以取得此堆積區塊的指標。

-l
讓調試程式偵測流失的堆積區塊。

-iAddress-h HeapAddress
顯示指定 堆積的相關信息。

地址
指定要搜尋的位址。

-?
在 [調試程式命令] 視窗中顯示此延伸模組的簡短說明文字。 針對一般說明使用 !heap -?頁面堆積說明的 !heap -p ?

NT 堆積參數

這些參數只適用於NT堆積。

HeapOptions
可以是下列選項的任何組合。 HeapOptions 值會區分大小寫。

選項 影響

-v

讓調試程式驗證指定的堆積。

注意 此選項不會偵測低片段堆積 (LFH) 損毀。 請改用 -triage

-a

讓顯示包含指定堆積的所有資訊。 在此情況下,大小會四捨五入至堆積數據粒度。 (使用 -a 選項執行 !堆積相當於使用三個選項 -h -f -m 執行它,這可能需要很長的時間。

-h

讓顯示包含指定堆積的所有非 LFH 專案。

-H l

讓顯示包含指定堆積的所有專案,包括 LFH 專案。

-F

讓顯示包含指定堆積的所有可用清單專案。

-m

讓顯示包含指定堆積的所有區段專案。

-t

讓顯示包含指定堆積的標記資訊。

-T

讓顯示包含指定堆積的虛擬標記專案。

-g

導致顯示包含全域標記資訊。 全域標記會與每個未標記的配置相關聯。

-s

導致顯示包含指定堆積的摘要資訊。

-k

(僅限 x86 型目標)讓顯示包含與每個項目相關聯的堆疊回溯。

ValidationOptions
可以是下列任一選項。 ValidationOptions 會區分大小寫。

選項 影響

-D

停用指定堆積的驗證時呼叫。

-E

啟用指定堆積的驗證時呼叫。

-D

停用指定堆積的堆積檢查。

-e

啟用指定堆積的堆積檢查。

-i堆積位址堆積位址
顯示指定 堆積的相關信息。

BreakAddress
指定要設定或移除斷點之區塊的位址。

-B
讓調試程式在堆積管理員中建立條件斷點。 -b 選項後面可以接著allocreallocfree;這會指定是否要透過配置、重新配置或釋放記憶體來啟動斷點。 如果使用 BreakAddress 來指定區塊的位址,則可以省略斷點類型。 如果使用 堆積來指定堆積 位址或堆積索引,則必須包含類型,以及 Tag 參數。

標籤
指定堆積內的標記名稱。

-B
讓調試程式從堆積管理員中移除條件斷點。 必須指定斷點類型(allocreallocfree),而且必須與與 -b 選項搭配使用的斷點類型相同。

StatHeapAddress
指定堆積的位址。 如果這是 0 或省略,則會顯示與目前進程相關聯的所有堆積。

-p
指定要求頁面堆積資訊。 如果不使用任何 PageHeapOptions,則會顯示所有頁面堆積。

PageHeapOptions
可以是下列任一選項。 PageHeapOptions 會區分大小寫。 如果未指定任何選項,則會顯示所有可能的頁面堆積句柄。

選項 影響

-h句柄

讓調試程序顯示具有 Handle 之頁面堆積的詳細資訊。

-a位址

讓調試程式尋找其區塊包含 Address 的頁面堆積。 將包含此位址與完整頁面堆積區塊相關的完整詳細數據,例如此位址是否為頁面堆積的一部分、區塊內的位移,以及已配置區塊或已釋放區塊。 每當可用時,就會包含堆疊追蹤。 使用此選項時,大小會顯示在堆積配置粒度的倍數中。

-t[c|s] [Traces]

讓調試程序顯示大量堆積使用者的收集追蹤。 追蹤會指定要顯示的追蹤數目;預設值為四。 如果追蹤數目超過指定的數位,則會顯示最早的追蹤。 如果使用 -t-tc ,追蹤會依計數使用量排序。 如果使用 -ts ,追蹤會依大小排序。 (僅限 Windows XP 支援 -tc-ts 選項;只有 Windows XP 和舊版 Windows 才支援 -t 選項。

-fi [追蹤]

讓調試程序顯示最新的錯誤插入追蹤。 追蹤會指定要顯示的數量;預設值為 4。

-所有

讓調試程序顯示所有頁面堆積的詳細資訊。

-?

讓調試程序顯示頁面堆積說明,包括堆積區塊的圖表。 (下列一節也可以看到這些圖表。

您必須先為您的目標進程啟用頁面堆積,才能使用任何 !heap -p 擴充功能命令。 請參閱下列一節中的詳細數據。

-srch
掃描指定模式的所有堆積。

模式
指定要尋找的模式。

大小
可以是下列任一選項。 這會指定模式的大小。 需要 『-』。

選項 影響

-B

此模式的大小為一個 BYTE。

-w

此模式的大小為一個 WORD。

-D

此模式的大小為一個 DWORD。

-q

此模式的大小為一個 QWORD。

如果未指定上述任何專案,則會假設模式的大小與計算機指標相同。

-外語
限制顯示只包含具有指定大小或大小的堆積。

FilterOptions
可以是下列任一選項。 FilterOptions 會區分大小寫。

選項 影響

s大小

限制顯示只包含指定大小的堆積。

rSizeMinSizeMax

限制顯示只包含指定大小範圍內的堆積。

-統計
顯示指定堆積的使用方式統計數據。

-h句柄
只會顯示 Handle堆積的使用量統計數據。 如果 Handle 為 0 或省略,則會顯示所有堆積的使用量統計數據。

-grpGroupBy
重新排序 GroupBy指定的顯示。 下表提供 GroupBy 的選項

選項 影響

A

根據配置大小顯示使用量統計數據。

B

根據區塊計數顯示使用量統計數據。

S

根據每個配置的總大小顯示使用量統計數據。

MaxDisplay
將輸出限制為僅 MaxDisplay 行數。

DLL

Windows XP 和更新版本

Ext.dll Exts.dll

其他資訊

如需堆積的相關信息,請參閱下列資源:

書: Microsoft Windows 內部 由馬克·魯西諾維奇和大衛·所羅門。

範例 11:啟用頁面堆積驗證

範例 12:使用頁面堆積驗證來尋找 Bug

如需使用堆積記憶體進程記錄器的詳細資訊,請參閱 範例 11:啟動私人追蹤會話

備註

此擴充功能命令可用來執行各種工作。

標準 !heap 命令可用來顯示目前進程的堆積資訊。 (這隻應用於使用者模式進程。 !pool 擴充功能命令應該用於系統進程。)

!heap -b!heap -B 命令可用來在堆積管理員中建立和刪除條件式斷點。

!heap -l 命令會偵測洩漏的堆積區塊。 它會使用垃圾收集行程演算法來偵測進程位址空間中任何位置未參考之堆積的所有忙碌區塊。 對於大型應用程式,可能需要幾分鐘的時間才能完成。 此命令僅適用於 Windows XP 和更新版本的 Windows。

!heap -x 命令會搜尋包含指定位址的堆積區塊。 如果使用 -v 選項,此命令會另外搜尋目前進程的整個虛擬記憶體空間,以尋找此堆積區塊的指標。 此命令僅適用於 Windows XP 和更新版本的 Windows。

!heap -p 命令會顯示各種形式的頁面堆積資訊。 使用 !heap -p 之前,您必須啟用目標進程的頁面堆積。 這是透過全域旗標 (gflags.exe) 公用程式來完成。 若要這樣做,請啟動公用程式,在 [映像檔名稱] 文本框中填入目標應用程式的名稱,選取 [圖像檔案選項] 和 [啟用頁面堆積],然後選取 [套用]。 或者,您也可以從命令提示字元窗口啟動全局旗標公用程式,方法是輸入 gflags /ixxx.exe+hpa,其中xxx.exe是目標應用程式的名稱。

Windows XP 以外不支援 !heap -p -t[c|s] 命令。 使用調試程式套件所提供的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搭配標頭位址,後面接著具有區塊的 StackTrace 欄位的 dds。