【问题标题】:how to use windbg track memory allocated with VirtualAlloc?如何使用通过 VirtualAlloc 分配的 windbg 轨道内存?
【发布时间】:2011-08-25 17:20:05
【问题描述】:

您知道如何使用带有 +ust 的 gflags 来获取与每个分配配对的调用堆栈。然后你可以在windbg中使用!heap来诊断泄漏吗?

我想通过 VirtualAlloc 进行大量分配。据我所知,VirtualAlloc 绕过了 gflags/!heap 扩展?

希望有人能确认

a) !heap 遍历每个堆中分配的内存列表 - 但不是来自 VirtualAlloc 的分配内存

b) 当你通过 new/malloc 分配一大块内存时,它会转到 LocalAlloc(),然后转到 VirtualAlloc(),它会绕过调用堆栈日志记录

我真的希望有人可以帮助我调试这种泄漏。如果分配更小,我对 !heap 没有任何问题

【问题讨论】:

    标签: winapi windbg heap-memory


    【解决方案1】:

    您可以尝试 LeakDiag,它适用于多种不同类型的内存,包括源自 VirtualAlloc 的内存。

    【讨论】:

      【解决方案2】:

      堆函数在比Virtual* 函数更高的级别上运行;实际上,堆必须调用 VirtualAlloc 来为进程地址空间添加更多内存。 !heap 不会帮助您处理 Virtual* 电话。

      【讨论】:

      • 了解,但是看起来对 HeapAlloc() 的大量调用会直接短路到未跟踪的 VirtualAlloc()。我没有直接调用 VirtualAlloc
      【解决方案3】:

      背景

      操作系统仅通过 VirtualAlloc() 提供内存。效果很好,但是粒度不好:一次只能提供 64kB。这就是为什么微软已经实现了不同的堆管理器,例如C++ 堆管理器或 .NET 堆管理器。那些从操作系统以 64kB 块的形式获取内存,并以较小的块将其提供给 C++ 或 .NET 程序。

      !heap 和相关命令仅适用于 C++ 堆管理器。要检查 .NET 堆,您需要 WinDbg 的 扩展。

      关于您的问题

      据我所知,VirtualAlloc 绕过了 gflags/!heap 扩展?

      GFlags +ust 标志特定于 C++ 堆分配。 !heap 命令也特定于 C++ 堆管理器,所以是的,这些都不会关心 VirtualAlloc() 调用。

      但是,我不会说,VirtualAlloc()“绕过”它们,这将是它通过 C++ 堆管理器的声明。恰恰相反:它比堆管理器操作的级别更低。

      a) !heap 遍历每个堆中分配的内存列表 - 但不是来自 VirtualAlloc 的分配内存

      是的,出于同样的原因。

      基本上是的。有一点不再值得将内存分成更小的区域。显然为一个 2 字节的变量分配 64kB 太浪费了。

      Microsoft 在大约 512 kB 处绘制了这条线,如 HeapAlloc 中所述(查找术语 0x7FFF8)。因此,当您分配超过 512 kB 时,它将不再使用堆管理器,而是使用 VirtualAlloc() 的原始内存块。在最坏的情况下,会有 12% 的开销(分配 512kB + 1 字节时会浪费 64kB)。

      别担心

      还有其他工具可以识别由 VirtualAlloc() 引起的更大内存泄漏。 WinDbg 命令!address 很有帮助,Rohitab API monitor 可以提供帮助。根据其他人的建议,您也可以尝试 LeakDiag 或商业内存泄漏分析器。

      【讨论】:

        猜你喜欢
        • 2014-05-22
        • 1970-01-01
        • 2011-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 1970-01-01
        • 2011-06-01
        相关资源
        最近更新 更多