讲述内存碎片的故事(与内存泄漏相反)?

hyt*_*ayr 2 windows memory-leaks memory-management windbg

首先我意识到泄漏会严重破坏内存,但请耐心等待.

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

谢谢!

小智 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)
Run Code Online (Sandbox Code Playgroud)

您可以使用!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)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.