天天看點

軟體調試23章 堆管理器向記憶體管理器釋放的疑惑

    張銀奎老師的<軟體調試>第23章提到可以用windbg !heap -v HeapHandle來檢視堆解除送出的粒度。我在win7 32bit機器上測試系統堆解除送出的情況,得到了不同的結果。

    首先我的系統堆位址是0x360000:

0:001> !heap -a
Index   Address  Name      Debugging options enabled
  1:   00360000 
    Segment at 00360000 to 00460000 (00028000 bytes committed)
  2:   00010000  - heap headers inaccessible, skipping
  3:   00020000  - heap headers inaccessible, skipping
  4:   00320000 
    Segment at 00320000 to 00330000 (00005000 bytes committed)      

    系統堆解除送出的粒度是0x2000,是以0x2000*8=0x10000=65536B,即堆上有64KB的空閑記憶體就會釋放記憶體。

0:001> !heap -v 0x00360000 
Index   Address  Name      Debugging options enabled
  1:   00360000 
    Segment at 00360000 to 00460000 (00028000 bytes committed)
    Flags:                00000002
    ForceFlags:           00000000
    Granularity:          8 bytes
    Segment Reserve:      00100000
    Segment Commit:       00002000
    DeCommit Block Thres: 00000800
    DeCommit Total Thres: 00002000
    Total Free Size:      000003ad      
軟體調試23章 堆管理器向記憶體管理器釋放的疑惑
軟體調試23章 堆管理器向記憶體管理器釋放的疑惑
軟體調試23章 堆管理器向記憶體管理器釋放的疑惑

3張圖依次是配置設定堆塊前,配置設定後,釋放後,程式在任務管理器中顯示的vm大小。

可以看到配置設定和釋放前後,vm的大小沒有改變。

這就很奇怪了,我不斷嘗試增加申請和釋放的堆記憶體數量,直到配置設定釋放的堆記憶體數量接近512KB時候,在任務管理器中有明顯的decommit動作。

軟體調試23章 堆管理器向記憶體管理器釋放的疑惑
軟體調試23章 堆管理器向記憶體管理器釋放的疑惑
軟體調試23章 堆管理器向記憶體管理器釋放的疑惑

最後,我檢視peb中關于堆釋放的粒度總算找到了解釋這個疑惑的點:

0:001> dt _peb @$peb
HiHeapVC8!_PEB
   +0x080 HeapDeCommitTotalFreeThreshold : 0x10000
   +0x084 HeapDeCommitFreeBlockThreshold : 0x1000      

繼續閱讀