DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在大型项目中,内存泄露并不会立即crash,会使系统性能不断下降,甚至因内存耗尽而崩溃。排查起来难度也比较大,申请内存的地方很多。这里介绍的这种方法可以迅速定位问题。

下面的程序crash64,每秒会申请1M的内存,而一直都没有释放,产生内存泄露

 

windbg 中有个小工具 UMDH可以追踪系统每个进程堆分配和释放的过程,通过分析比较能够对比出哪一次分配的堆空间没有释放。

 

开启堆信息追踪 ,命令如下

gflags /i ImageName +ust    

mageName表示进程名字

这里输入gflags /i crash64.exe +ust

 

通过设置环境变量_NT_SYMBOL_PATH,UMDH可以找对应的PDB符号文件

这里的符号文件包括两部分,

一是系统的,例如NTDLL,MSVCR100, kernel32等等

二是我们程序的

因此我配置的环境变量如下

SRV*c:\symbols*http://msdl.microsoft.com/download/symbols;D:\sample\crash64\x64\Release

这样配置就完成了 可以开始分析了

 

这时再次运行crash64.exe ,打开PE 找到PID 为4800

CMD中输入umdh -p:4800 -f:d:\crash64old.log

 

此时保存了一个日志文件到D盘

等一段时间 观察PE的内存趋势图,感觉发生了内存泄露后 我这个是每秒钟都会发生一次内存泄露 所以不用看PE了

再次输入 umdh -p:4800-f:d:\crash64new.log

d:\crash64old.log d:\crash64new.log 名字都是可以随便起的

又保存了一个日志到D盘

现在输入umdh -d d:\crash64old.logd:\crash64new.log > d:\crash64.txt

UMDH就开始比较这两个日志文件了 并将比较的结果存在crash64.txt中

 

 

注意这里的文件名需要是绝对路径 不然就定位到systerm32目录中去了上面我就搞错了次

这时打开crash64.txt

 

                                           

+ 234873856 ( 350213696 - 115339840)    334 allocs    BackTrace75D00

+    224 (    334 -    110) BackTrace75D00 allocations

 

       ntdll!?? ::FNODOBFM::`string'+0001913B

       MSVCR100!malloc+0000005B

       MSVCR100!operatornew+0000001F

       crash64!wmain+00000036(d:\sample\crash64\crash64\crash64.cpp, 16)

       crash64!__tmainCRTStartup+0000011A(f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c, 552)

       kernel32!BaseThreadInitThunk+0000000D

       ntdll!RtlUserThreadStart+0000001D

 

 

Total increase == 234873856 requested+   7168 overhead = 234881024

 

结果出来拉

+234873856表示增加的内存字节

+224表示增加申请的次数

234873856 /224 = 1,048,544 = 1024 * 1023 跟代码中实际现象一样

(怎么不是1024 *1024 是1024*1023?)

申请的位置在crash64.cpp中的16行

正是 这句 p = newchar[1024 * 1024];

posted on 2021-02-06 15:37  DoubleLi  阅读(440)  评论(0编辑  收藏  举报