告诉内存碎片(而不是内存泄漏)的故事标志?

首先,我意识到泄漏会严重影响记忆,但请耐心等待。

  • 使用WinDbg并附加到一个进程:使用!堆(或另一个WinDbg命令),我应该期待看看如果我处理内存碎片而不是泄漏? 例如,我可以使用“!heap stat”和“!heap stat -h handle”来对产生泄漏的代码进行归零; 但是在这些相同的返回值中是否有某些暗示碎片的东西呢?
  • XP和Vista之间的内存分配是否发生了根本性的变化? 特别是与DLL和其他库加载有关吗? 我们一直在开发专门的XP,所以我不熟悉Vista,但事实certificate,我们在XP上看到的某些内存问题在Vista上安装相同的二进制文件时就消失了。

谢谢!

对不起,我不能帮助你解决问题,所以我只想解决你的第二个问题。

Vista引入了ASLR,它改变了DLL加载的方式。 欲了解更多信息,请参阅这个维基条目和更具体的讨论这个职位可能是有用的。

有几种不同的碎片:地址空间碎片和堆碎片。 前者可能会导致失败扩展托管堆或非托管堆,或者未能加载DLL,后者可能导致调用new内存分配失败。

您可以使用!address -summary来获得地址空间的概述。 这告诉你有多少空间是空闲的,提交的,用于DLL映射,虚拟地址描述符(元数据)等等。sysinternals VMMap工具为你提供了一个图形视图,而不需要调试器。

对于堆碎片来说,堆堆的输出应该包含一些关于非堆积堆的碎片的指示,例如:

 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) 

希望这可以帮助。

从Windows Vista开始,默认情况下会启用一个新的内存管理器,称为低碎片堆(m2)。

MS描述

对于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)); }