我正在尝试调试64位C ++本机应用程序中的内存泄漏。该应用每秒通过7-10次泄漏1300个字节-通过普通的malloc()。
如果我使用WinDBG附加该进程并每60秒中断一次,则!heap不会显示分配的内存的任何增加。
我确实在该过程中启用了用户模式堆栈跟踪数据库:
gflags /i <process>.exe +ust
在WinDBG(已成功加载所有符号)中,我正在使用:
!heap -stat -h
但是即使我看到任务管理器和PerfMon跟踪中的“私人字节数”增加,当中断时,命令的输出也不会改变。
我知道,当分配较小时,它们转到HeapAlloc(),当分配较大时,它们转到VirtualAlloc。 !heap对HeapAlloc不起作用吗?
这个post似乎暗示也许使用DebugDiag可以工作,但是仍然归结为使用WinDBG命令来处理转储。尝试无济于事。
此post还表示,对于64位应用程序,!heap命令已损坏。可能是这样吗?
是否存在用于诊断64位应用程序中泄漏的备用过程?
答案 0 :(得分:0)
!!堆没有显示已分配的内存的任何增加。
这可能取决于您要查看的列以及堆管理器之前分配的内存量。
例如您的应用程序可能有100 MB的堆,其中只有64kB的某些块正在从“保留”列移至“已提交”列。如果内存是从一开始就提交的,那么使用普通的!heap
命令根本看不到任何内容。
我确实在进程中启用了用户模式堆栈跟踪数据库
这将帮助您获取分配堆栈跟踪,但通常不会影响泄漏。
我知道,当分配较小时,它们转到HeapAlloc(),当分配较大时,它们转到VirtualAlloc。
!heap对HeapAlloc无效吗?
应该。而且由于C ++ malloc()
和new
都使用Windows Heap管理器,所以它们迟早会导致HeapAlloc()
。
以下代码
#include <iostream>
#include <chrono>
#include <thread>
int main()
{
// https://stackoverflow.com/questions/53157722/windbg-diagnosing-leaks-in-64-bit-dumps-heap-not-showing-memory-growth
//
// I am trying to debug a memory leak in a 64-bit C++ native application.
// The app leaks 1300 bytes 7-10 times a second - via plain malloc().
for(int seconds=0; seconds < 60; seconds++)
{
for (int leakspersecond=0; leakspersecond<8;leakspersecond++)
{
if (malloc(1300)==nullptr)
{
std::cout << "Out of memory. That was unexpected in this simple demo." << std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(125));
}
}
}
编译为64位版本,并在WinDbg 10.0.15063.400 x64显示中运行
0:001> !heap -stat -h
Allocations statistics for
heap @ 00000000000d0000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
514 1a - 8408 (32.24)
521 c - 3d8c (15.03)
[...]
及以后
0:001> !heap -stat -h
Allocations statistics for
heap @ 00000000000d0000
group-by: TOTSIZE max-display: 20
size #blocks total ( %) (percent of total busy bytes)
514 30 - f3c0 (41.83)
521 18 - 7b18 (21.12)
即使未设置+ust
。
这是450万行代码。
那么您如何知道它通过普通的malloc()泄漏了1300个字节?