首先我意识到泄漏会严重破坏记忆,但请耐心等待。
谢谢!
答案 0 :(得分:9)
有几种不同的碎片:地址空间碎片和堆碎片。前者可能导致无法扩展托管或非托管堆,或者无法加载DLL,后者可能会在调用new
时导致内存分配失败。
您可以使用!address -summary
来概述地址空间。这告诉您有多少空间是空闲,已提交,用于DLL映射,虚拟地址描述符(元数据)等.sysinternals VMMap工具为您提供了它的图形视图,而无需调试器。
对于堆碎片,!heap -s
的输出应该包括碎片非托管堆的一些指示,例如:
00970000 00001002 64576 39232 49736 5732 1314 448 0 1 L
External fragmentation 14 % (1314 free blocks)
Virtual address fragmentation 21 % (448 uncommited ranges)
您可以使用!heap -stat
进行深入研究,例如!heap -stat -h 00970000
给出上面的输出,这将告诉你分配大小等的分布。这对于看看你是否有大量的小对象很有用,假设你没有使用低碎片堆,例如:
0:057> !heap -stat -h 00970000
heap @ 00970000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
134 c0c8 - e7f0a0 (50.72)
18 ee22 - 165330 (4.88)
8c 26f9 - 15502c (4.66)
a4 1ffc - 147d70 (4.48)
希望这有帮助。
答案 1 :(得分:2)
对不起,我无法帮助解决碎片问题,所以我只想解决你的第二个问题。
Vista引入了ASLR,它改变了DLL的加载方式。有关详细信息,请参阅此wiki entry,有关更具体的讨论this post可能会有用。
答案 2 :(得分:2)
从Windows Vista开始,默认启用新的内存管理器,称为低碎片堆(m2)。
对于Windows XP,您可以使用以下代码启用低碎片堆:
HANDLE heaps[1025];
DWORD nheaps = GetProcessHeaps((sizeof(heaps) / sizeof(HANDLE)) - 1, heaps);
for (DWORD i = 0; i < nheaps; ++i) {
ULONG enableLFH = 2;
HeapSetInformation(heaps[i], HeapCompatibilityInformation, &enableLFH, sizeof(enableLFH));
}