您不能使用 WinDbg 闯入 .NET 应用程序,然后同时运行 VMMap。这将导致 VMMap 挂起。您也不能反其道而行之:先启动 VMMap,然后进入 WinDbg,然后刷新 VMMap 中的值。
因此,VMMap 显示的值可能永远不会相等,因为这些数字来自不同的时间点。不同的时间点也可能意味着垃圾收集器已经运行。如果应用程序变化不大,则值应该接近。
在我的测试中,VMMap 中托管堆的已提交部分是 和 的总和!eeheap -gc
,!eeheap -loader
这听起来很合理。
给定 的输出!eeheap -gc
,我们在第 2 代 (11aa0000) 处开始 GC 堆,大小仅为 3.6 MB。
Number of GC Heaps: 1
generation 0 starts at 0x0000000011d110f8
generation 1 starts at 0x0000000011cd1130
generation 2 starts at 0x0000000011aa1000
...
GC Heap Size 0x374a00(3623424)
!address
给出详细信息:
...
+ 0`11aa0000 0`11ef2000 0`00452000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE <unknown>
0`11ef2000 0`21aa0000 0`0fbae000 MEM_PRIVATE MEM_RESERVE <unknown>
0`21aa0000 0`21ac2000 0`00022000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE <unknown>
0`21ac2000 0`29aa0000 0`07fde000 MEM_PRIVATE MEM_RESERVE <unknown>
+ 0`29aa0000 0`6ca20000 0`42f80000 MEM_FREE PAGE_NOACCESS Free
...
虽然没有记录,但我相信一个新段从 11aa0000 开始,由+
符号指示。GC 段在 29aa0000 结束,这也是下一段的起点。交叉检查:.NET 内存应该<unknown>
在最后一列中报告 - 好的。
总 GC 大小(保留 + 已提交)为
?29aa0000-11aa0000
Evaluate expression: 402653184 = 00000000`18000000
这是 402 MB 或 393.216 kB,在我的情况下非常接近 VMMap 报告的 395.648 kB。
如果你有更多的 GC 堆,整个过程需要更多的努力。因此,我通常采用捷径,如果您知道除了调用 VirtualAlloc() 的 .NET 之外没有其他任何东西,那就可以了。键入!address -summary
然后查看第一个<unknown>
条目:
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 144 7ff`d8a09000 ( 7.999 Tb) 99.99%
<unknown> 180 0`1a718000 ( 423.094 Mb) 67.17% 0.01%
...