Windows 内存碎片的迹象(与内存泄漏相反)?
首先,我意识到泄漏会严重破坏内存,但请容忍我Windows 内存碎片的迹象(与内存泄漏相反)?,windows,memory-management,memory-leaks,windbg,Windows,Memory Management,Memory Leaks,Windbg,首先,我意识到泄漏会严重破坏内存,但请容忍我 使用WinDbg并附加到进程:使用!heap(或另一个WinDbg命令),如果我处理的是内存碎片而不是泄漏,我应该看到什么?例如,我可以使用“!heap stat”和“!heap stat-h handle”来确定生成泄漏的代码;但是,在这些相同的返回值中,是否有什么东西会暗示碎片 XP和Vista之间的内存分配是否发生了根本性的变化?特别是与DLL和其他库加载相关的?我们只在XP上开发,所以我不熟悉Vista,但事实证明,当我们在Vista上安装
- 使用WinDbg并附加到进程:使用!heap(或另一个WinDbg命令),如果我处理的是内存碎片而不是泄漏,我应该看到什么?例如,我可以使用“!heap stat”和“!heap stat-h handle”来确定生成泄漏的代码;但是,在这些相同的返回值中,是否有什么东西会暗示碎片
- XP和Vista之间的内存分配是否发生了根本性的变化?特别是与DLL和其他库加载相关的?我们只在XP上开发,所以我不熟悉Vista,但事实证明,当我们在Vista上安装相同的二进制文件时,我们在XP上看到的某些内存问题消失了李>
谢谢 很抱歉,我无法帮助您解决碎片问题,因此我只想回答您的第二个问题
Vista引入了ASLR,它改变了DLL的加载方式。有关更多信息,请参阅此内容,并了解可能有用的更具体的讨论。从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));
}
处理堆[1025];
DWORD nheaps=GetProcessHeaps((sizeof(heaps)/sizeof(HANDLE))-1,heaps;
对于(DWORD i=0;i
有两种不同类型的碎片:地址空间碎片和堆碎片。前者可能导致扩展托管堆或非托管堆失败,或加载DLL失败,后者可能导致调用new
时内存分配失败
您可以使用!地址-摘要
以获取地址空间的概览。这将告诉您有多少可用空间、提交空间、用于DLL映射、虚拟地址描述符(元数据)等。sysinternals工具为您提供了它的图形视图,而无需调试器
对于堆碎片,的输出!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)
您可以使用深入了解这一点!堆-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)
希望这有帮助。值得注意的是,您可以通过检查
中的相同输出来确认低碎片堆已打开!堆-s
。如果启用了低碎片堆,行末尾的“L”将更改为“LFH”。在第一段中,您是否意外地颠倒了“前者”和“后者”的用法我认为地址空间碎片会导致new
的内存分配失败,而堆碎片会导致堆扩展失败。