如何在所有堆中使用umdh.exe跟踪内存泄漏?

时间:2009-04-03 08:06:02

标签: c++ memory-leaks

我有一个c ++ windows应用程序,每个事务都会泄漏内存。使用perfmon我可以看到私有字节随着每个事务而增加,当应用程序空闲时内存使用率是平的。

根据stackoverflow的先前答案,我使用微软调试工具中的umdh来追踪一个内存泄漏。然而,还有更多泄漏,umdh的结果与我的perfmon结果不匹配。

首先,umdh仍会报告此泄漏,堆栈跟踪为:

+   36192 ( 2082056 - 2045864)    251 allocs    BackTraceCB
+       4 (    251 -    247)    BackTraceCB allocations

    ntdll!RtlAllocateHeapSlowly+00000041
    ntdll!RtlAllocateHeap+00000E9F
    MSVCR80!malloc+0000007A

这是没有用的,因为第一个调用是malloc,它没有说出它叫什么。我对这个泄漏有疑问,因为它在应用程序处理事务和空闲时报告。但我可以清楚地看到,闲置时没有内存泄漏。处理事务时报告的内存泄漏与作为perfmon报告处理的事务不成比例。

umhd没有显示任何其他泄漏,但我知道至少还有一个没有显示。我刚从搜索网络中了解到Windows应用程序可以有多个堆。

  • 是不是umhd只报告其中一个堆的内存使用情况?例如,默认或crt堆?
  • 如何跟踪其他堆中的内存使用情况?
  • 如何找出dll / modules正在使用其他堆?

任何关于追踪此问题的指示都会感激不尽,因为我的选项已用完。

5 个答案:

答案 0 :(得分:3)

对我来说,在umdh失败的情况下 - 另一个名为LeakDiag的MS免费工具成功了。它允许拦截比umdh更多的分配器类型,包括它所谓的'MPHeap allocator',I suspect可能对你有用。如果你有空闲时间 - 我很好奇这是否确实有帮助..

答案 1 :(得分:1)

除非您的应用程序(或它使用的库)显式创建自己的堆,否则只需要担心一个堆。大多数图书馆都不这样做,所以我建议这不应该是你调查的主要途径。

答案 2 :(得分:1)

也许umdh无法为您的代码找到调试符号?这可能解释了为什么堆栈跟踪不完整。确保你已经用符号构建它并且可以找到它们。

答案 3 :(得分:1)

很抱歉回答我自己的问题,但我最终将问题跟踪到了如何使用Orbix。

它表示orbix库在windows平台上使用自己的堆。这意味着大多数内存泄漏检测不适用于orbix中的泄漏,我尝试了boundschecker和umhd.exe。

为了隔离这个问题,我发现了一些代码会转储应用程序中每个堆的内存:http://www.abstraction.net/content/articles/analyzing%20the%20heaps%20of%20a%20win32%20process.htm

我使用它来转储每个事务之前和之后的堆使用情况,然后在每500个事务之后,这表明每次都在增加相同的堆。然后我列出了这个堆中每个条目的地址。检查这些区域的内存,我发现这些包含了orbix编组数据。有了这些信息,我终于找到了一些未被清理的对象引用。

答案 4 :(得分:0)

我用来进行代码审查以寻找内存泄漏。

我正在寻找的一些事情:

  1. 继承问题:不提供虚拟析构函数且以多态方式使用的基类。
  2. 在代码中搜索指针声明或指针分配(查找*声明,或关键字new或malloc用法),并查看代码段,定位动态分配对象的生命周期。
  3. 当然,代码审查可能非常耗时,具体取决于您必须查看的代码库。但是,如果你可以限制你需要寻找指针分配/使用的区域,它可能会回报。它在我的大多数情况下都有。