【问题标题】:Tell tale sign of memory fragmentation (as opposed to a memory leak)?告诉内存碎片的迹象(而不是内存泄漏)?
【发布时间】:2009-09-28 15:25:45
【问题描述】:

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

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

谢谢!

【问题讨论】:

    标签: windows memory-management memory-leaks windbg


    【解决方案1】:

    有几种不同的碎片:地址空间碎片和堆碎片。前者可能导致扩展托管或非托管堆失败,或加载 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)
    

    希望这会有所帮助。

    【讨论】:

    • 值得注意的是,您可以通过检查来自!heap -s 的相同输出来确认低碎片堆已打开。如果启用低碎片堆,则行尾的“L”将更改为“LFH”。
    • 在第一段中,您是否不小心将“前”和“后”的用法颠倒了?我认为地址空间碎片会导致new 的内存分配失败,而堆碎片会导致堆扩展失败。
    【解决方案2】:

    很抱歉,我无法帮助您解决碎片问题,所以我只解决您的第二个问题。

    Vista 引入了 ASLR,它改变了 DLL 的加载方式。如需更多信息,请参阅此wiki entry,对于更具体的讨论,this post 可能会有用。

    【讨论】:

      【解决方案3】:

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

      MS Description

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

      【讨论】:

        猜你喜欢
        • 2020-02-15
        • 2014-06-22
        • 2012-08-17
        • 2011-01-21
        • 2013-09-23
        • 2011-10-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多