UMDH帮助排查内存持续增长问题

1.简介

umdhwindows debug tools下的一款命令行工具,它的全名是User-Mode Dump Heap 这个工具会分析当前进程在堆上分配的内存,通过命令操作,可以对当前进程分配的每一块内存做日志记录,其中包含分配的内存大小、内存分配地址、内存分配时的函数调用堆栈等;还可以通多命令操作,比较几个顺序时间的日志记录,找出内存增长的位置。

2.步骤

在已经安装windbg的情况下,使用umdh排查内存增长问题的步骤如下:

1) 配置系统 环境变量设置

变量名:_NT_SYMBOL_PATH

变量值:SRV*C:\Windows\symbols*http://msdl.microsoft.com/download/symbols;E:\pdb

(windbg加载pdb的路径)

注意:E:\pdb指加载调试程序的pdb文件路径,如果有多个路径可以用‘;’分开添加;C:\Windows\symbols指向windows系统自己的pdb文件,windows系统的pdb文件在调试的时候其会自动从windows官网上下载。

设置环境变量后VS在启动程序时会自动加载_NT_SYMBOL_PATH下的pdb文件,会使调试程序较慢,所以在不需要时,建议把它去掉。

2)开启cmd

以管理员身份运行cmd,并进入windbg存在的路径下,如:

cd C:\Program Files\Debugging Tools for Windows (x64)

注意:windbg和程序的位数要一致,这里是64位的;

3)创建用户态堆栈追踪数据库   

gflags -i appname.exe(目标进程名称) +ust

4)利用umdh创建heap快照

umdh -p:目标进程 ID -f:E:\umdh\log1.txt(输出日志文件)

或者

umdh -pn:appname.exe(目标进程名称) -f:E:\umdh\log1.txt(输出日志文件)

程序运行一段时间后,再次创建heap快照,命令无差别,log1.txt改为log2.txt;

5)比较分析heap前后两个快照的差异

umdh -d E:\umdh\log1.txt E:\umdh\log2.txt > E:\umdh\cmp12.txt

3.Demo分析内存泄漏

【demo代码】

int main()
{
       for (int i = 0; i < 10000; i++)
       {
              char *p = new char[10240];
              memset(p, 0, 10240);
              Sleep(100);
       }
}

Release32编译生成程序名称为demo.exe,demo.exe与demo.pdb路径为E:\umdh\release;

1)配置环境变量

值为:SRV*C:\Windows\symbols*http://msdl.microsoft.com/download/symbols;E:\umdh\release

2)开启cmd

进入32位的windbg路径下,如:

cd C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x86

3)运行demo.exe

只要在创建用户态堆栈追踪数据库之前运行程序就OK;通过任务管理器可以明显看到内存持续增长;

4)创建用户态堆栈追踪数据库

gflags -i demo.exe +ust

5)利用umdh创建heap快照

umdh -pn:demo.exe -f:E:\umdh\demo_log1.txt

等待一会时间后再次创建heap快照:

umdh -pn: demo.exe -f:E:\umdh\demo_log2.txt

6)比较分析heap前后两个快照的差异

umdh -d E:\umdh\demo_log1.txt E:\umdh\demo_log2.txt > E:\umdh\demo_cmp12.txt

执行该命令需要等待一段时间,应该是在加载pdb文件;

7)分析对比结果

执行完上述流程后吗,可以在E:\umdh路径下看到demo_log1.txt、demo_log2.txt、demo_cmp12.txt三个日志文件;现在分析对比结果demo_cmp12.txt文件,如下图:

对比文件从上到下展示了符号文件加载信息,具体内存泄露信息、总的内存增长信息;

具体的内存泄漏信息格式说明:

第一行:+ 4833280 ( 5765120 - 931840)    563 allocs   BackTrace2D2ED8

BackTrace2D2ED8是这个内存块的标,5765120是生成demo_log2.txt时该内存块的大小,931840是生成demo_log1.txt该内存块的大小,差值+4833280是指在这两个日志文件时间差内,内存分配的增长的字节数,563 是分配内存的次数;

第二行:+ 472 (    563 -     91)    BackTrace2D2ED8 allocations

BackTrace2D2ED8是内存块标记和第一行一样,563是生成demo_log2.txt时该内存分配的次数,91是生成demo_log1.txt时该内存分配的次数,差值472是在这两个日志文件时间差内,该内存块分配的次数。

其他行:是函数调用堆栈,通过分析程序发现,下面这三行

MSVCR120!malloc+49 (f:\dd\vctools\crt\crtw32\heap\malloc.c, 92)

MSVCR120!operator new+1D (f:\dd\vctools\crt\crtw32\heap\new.cpp, 59)

demo!main+15(d:\program\vs2013\test3\test3\main.cpp, 9)

很明显的指明了内存泄漏的位置,是因为调用了new分配内存,具体位置是\main.cpp文件中的第9行附近。

上述图中具体的内存泄漏信息中,只显示了一个内存分配追踪的动作,堆栈调用部分的最上面几行是系统内核最终调用分配函数。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值