Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 内存碎片的迹象(与内存泄漏相反)?_Windows_Memory Management_Memory Leaks_Windbg - Fatal编程技术网

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
的内存分配失败,而堆碎片会导致堆扩展失败。