C# 内存泄漏之 Internal 关键词代表什么?( 二 )

把堆上的 segment 和 block 都显示出来 。

C# 内存泄漏之 Internal 关键词代表什么?

文章插图
从图中可以看到,全是这种 Internel 的标记 , 而且 request size = 41fe8 = 270312 byte= 263k,很显然我并没有做 27w byte 的内存分配,那这些源自于哪里呢?
2. 源自于哪里?因为 前段堆 相当于堆中堆,所以我们观察下有没有开启LFH,有两种方法 。
  1. 观察 !heap -s 命令输出的 Fast heap 列是不是带有 LFH ?
  2. 观察 HEAPFrontEndHeap 字段是否为 null ?
0:000> dt nt!_HEAP 10600000ntdll!_HEAP+0x0e4 FrontEndHeap: 0x10570000 Void+0x0e8 FrontHeapLockCount : 0...接下来就是怎么把 FrontEndHeap 中的信息给导出来? 你完全可以根据这个首地址一步步的导出,也可以使用强大的 heap 扩展命令 -hl , 这里的 l 就是 LFH 的意思 。
0:000> !heap -hl 10600000LFH data region at 193a0018 (subsegment 106e4a30):193a0038: 02808 - busy (2734)193a2840: 02808 - busy (2734)193a5048: 02808 - busy (2734)193a7850: 02808 - busy (2734)193aa058: 02808 - busy (2734)193ac860: 02808 - busy (2734)193af068: 02808 - busy (2734)193b1870: 02808 - busy (2734)...LFH data region at 1cf02018 (subsegment 10695888):1cf02038: 02808 - busy (2734)1cf04840: 02808 - busy (2734)1cf07048: 02808 - busy (2734)1cf09850: 02808 - busy (2734)1cf0c058: 02808 - busy (2734)...可以看到有大量的 alloc = 02808 = 10248 byte 大小的 block  , 而且还有很多的 subsegment 字样,也说明了 Internel 的组成结构,由于记录了 ust,我们就可以使用 !heap -p -a 把这个block的调用栈给找出来 。
0:000> !heap -p -a 193a0038address 193a0038 found in_HEAP @ 10600000HEAP_ENTRY Size Prev FlagsUserPtr UserSize - state193a0038 0501 0000[00]193a005002734 - (busy)76f377a4 ntdll!RtlpCallInterceptRoutine+0x0000002676ef61ef ntdll!RtlpAllocateHeapInternal+0x00050ddf76ea53fe ntdll!RtlAllocateHeap+0x0000003e7b81bf35 ucrtbased!heap_alloc_dbg_internal+0x000001957b81bd46 ucrtbased!heap_alloc_dbg+0x000000367b81e4ba ucrtbased!_malloc_dbg+0x0000001a7b81edd4 ucrtbased!malloc+0x000000147b7621fd Example_16_1_7!InitData+0x000010ea7b7618cc Example_16_1_7!InitData+0x000007b97b76185e Example_16_1_7!InitData+0x0000074b...三:总结本篇主要是解析了 Internel 标记的可能来源地 , 没有对 LFH 做进一步的讲解,更多的 NtHeap 知识可以参考 《深入解析 Windows 操作系统》 一书 。

推荐阅读