关注:QStockView,获取股票智能分析报警软件
目录
1 简介... 1
2 检测内存泄漏的方法... 1
2.1 VS2015性能探测器... 1
2.2 VLD嵌入式分析... 4
2.3 windbg工具udmh解决定位内存泄漏方法... 9
2.4 LeakDiag内存泄漏分析LDGrapher查看... 13
3 四种方法比较... 17
1 简介
内存泄漏一直是比较头疼的问题,一个内存泄漏往往要排查,定位,修改,测试,再排查、定位,修改,测试,直到找到所有的内存泄漏位置,费时费力,如果通过查找new 或者malloc函数名称,然后再排查所有的申请的内存是否都销毁掉,一步步的按图索骥,查找内存是否闭环,这样也可以,但是如果是工程比较大,流程比较复杂的情况下,这种方法查找起来往往会耗费很大的精力和时间,而且如果是调用的依赖库发生了泄漏,这种方法是到死也找不到泄漏的地方的,所以一直寻求一中快速定位内存泄漏的方法,能够快速找到内存泄漏的代码位置,也能指出是哪个依赖库产生了内存泄漏;
2 检测内存泄漏的方法
2.1 VS2015性能探测器
(1)打开性能探测器,选中内存使用率,点击开始按钮;
(2)运行程序后,点击拍摄快照的按钮,运行一段时间抓一次快照;然后再点击左上角的停止按钮,vs2015会分析几分钟,最后得出分析报告;
(3)点击图中的停止按钮后,会产生分析报告,每次快照内存比上一次涨了多少,跌了多少;右键选中某个快照,然后选择要比对的快照1;
(4)用快照3和快照1对比发现,内存增加了5M左右,其中dhplay.dll内部内存增加了2.7M;这就是库内存泄漏,需要看dhplay.dll内部源码去找了;
(5),如果是你自己程序的代码泄漏,vs会自动定位到代码里函数名称;如下所示,new内存不删除,快照对比之后,可以定位到startSmartApart()函数
(6)更进一步,点击右上角的查看堆内存按钮,可以显示出堆栈中申请的内存对象是哪个类;按照计数差异排序;可以看到具体new的对象;根据对象名称去查找内存泄漏的地方;统计增加的次数和大小。
2.2 VLD嵌入式分析
Vld是要包含头文件和库文件,将vld集成到所要修改的程序中,也就是要加入库文件,包含头文件,并且加入几行代码,再重新编译程序,运行程序一段时间,然后关闭程序,再程序目录下会生成一个txt的文档,里面有内存泄漏的报告。
使用步骤
(1) 下载安装
链接:https://pan.baidu.com/s/1vpGYOvJrMLH9URubMC2NTg
提取码:关注微信公众号:QStockView,输入框发送内存泄漏,我立即发给你;另外还有股票软件可以下载;
这里勾选上,会自动将头文件目录加到VS2015的继承路径中;
打开这个包含路径,你会发现VLD的路径D:\Program Files (x86)\Visual Leak Detector\include已经被包含在项目中。
这种方法的弊端是引入的文件,如果你用svn或者github,你会发现videoplayer.vcxproj项目文件中包含 路径都加上了路径D:\Program Files (x86)\Visual Leak Detector\include,无法被删除。
卸载VLD都不行,你需要在目录C:\Users\Administrator\AppData\Local\Microsoft\MSBuild\v4.0中的找到文件Microsoft.Cpp.Win32.user.props,手动删除路径。然后在D:\mycomputername\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props,找到这个文件,删除里面的visual leak detector
(2) 在代码中嵌入VLD
在main.cpp文件的头部包含头文件
#define VLD_FORCE_ENABLE //release模式也能产生内存泄漏报告;
#include<vld.h>
在main函数的开头和结尾加上
int main(int argc, char *argv[])
{
//开头
VLDGlobalEnable();
VLDReportLeaks();//内存泄漏监测VLD,要装一个vld插件
//结尾
VLDGlobalDisable();
return 0;
}
(3) 修改vld的配置文件,在vld的安装目录有个vld.ini文件,将它复制到程序运行目录;
VLD = on //设置vld为on状态,表示检测内存泄漏
ForceIncludeModules = AVPSdk.dll;dhplay.dll;//默认只对exe的代码做内存泄漏检测,如果要检测依赖的库文件,需要用这个参数配置依赖库的名称,用分号隔开;
ReportFile =memory_leak_report.txt //输出泄漏报告的文件名称
(4) 程序运行一段时间,产生内存泄漏,然后关闭程序,就会输出报告到文件;部分报告如下所示。可以看到内存泄漏的库和函数名称,以及泄漏的大小;
---------- Block 56357 at 0x02DFAE40: 532 bytes ----------
Leak Hash: 0xB79B8570, Count: 1, Total 532 bytes
Call Stack (TID 2656):
ntdll.dll!RtlAllocateHeap()
dhplay.dll!PLAY_ReleaseDDrawDevice() + 0x2EF3C9 bytes
dhplay.dll!PLAY_ReleaseDDrawDevice() + 0x2F1C78 bytes
dhplay.dll!PLAY_ReleaseDDrawDevice() + 0x2EB81D bytes
dhplay.dll!PLAY_ReleaseDDrawDevice() + 0x2EB8D7 bytes
ntdll.dll!LdrDeleteEnclave() + 0xB6 bytes
ntdll.dll!RtlGetNtSystemRoot() + 0x6C bytes
ntdll.dll!RtlGetNtSystemRoot() + 0x282 bytes
ntdll.dll!LdrInitializeThunk() + 0xEB bytes
ntdll.dll!LdrInitializeThunk() + 0x11 bytes
Visual Leak Detector detected 1055 memory leaks (51636 bytes).
Largest number used: 297658989 bytes.
Total allocations: 4294967295 bytes.
Visual Leak Detector is now exiting.
2.3 windbg工具udmh解决定位内存泄漏方法
windbg是一个一个强大的分析工具,可以分析dmp文件,也可以分析内存泄漏;而且可以再程序运行过程中去去检测。截取程两个时间点的内存快照,然后通过两次快找的差异比较出内存泄漏的地方;
(1) 下载windbg工具安装,安装目录下有udmh.exe;
(2) 打开cmd程序,进入到windbg安装目录,或者将windbg安装目录加入系统环境变量,然后cmd输入命令可以识别到udmh命令;
(3) 运行被检测的程序,然后输入命令umdh -pn:videoplayer.exe -f:snap1.log
videoplayer.exe是要被检测的程序进程名称,snap1.log是要保存的快照文件名称;
在windbg的安装目录下会生成snap1.log,里面会记录内存申请情况;
(4) 运行一段时间后,查看内存增长情况,出现内存泄露后,再次在cmd中 输入命令umdh -pn:videoplayer.exe -f:snap2.log抓取快照2
(5) 用命令umdh -d snap1.log snap2.log -f:result.txt 比对两次快照,将结果保存到result.txt文件中输出泄漏的大小和结果;根据指定的位置解决泄漏;
2.4 LeakDiag内存泄漏分析LDGrapher查看
(1) 下载安装,下面得压缩包里就有两个安装包,leakDiag是用来检测程序,抓拍快照(保存内存数据到文件),LDGrapher则是将文件按照顺序和内存泄漏位置画出曲线图,可以很直观的看出内存的长势;
链接:https://pan.baidu.com/s/1vpGYOvJrMLH9URubMC2NTg
提取码:关注微信公众号:QStockView,输入框发送内存泄漏,我立即发给你;另外还有股票软件可以下载;
(2) 打开leakDiag.exe程序
(3) 点击Tools-Options打开配置界面,设置日志保存路径,配置检测程序的pdb文件路径
(4) 在Application列表中找到进程videoplayer.exe,有时候会找不到,刷新列表,重启程序都不显示进程,这时候要重启电脑才会显示进程,然后点Memory allocators列表中的Windows heap Allocator 最后点击start按钮;开始检测;有时候附加进程,还会导致进程直接崩溃。
(5) 隔一段时间点击一次log按钮,每点击一次就会抓取一次内存快照,保存到文件中;
(6) 打开LDGrapher.exe程序,点击左上角的file菜单,然后导入那些生产的内存快照文件;
(7) 导入之后,会生成内存泄漏的曲线,双击查看哪些成增长趋势的曲线;就会显示出内存泄漏的地方;
3 四种方法比较
泄漏检测方法 |
优点 |
缺点 |
VS2015性能探测器 |
Vs自带的探测功能,使用方便。 |
通过两次内存快照的比较判断泄漏,有时候不准 |
VLD嵌入式分析 |
内存泄漏检测定位准确。 |
需要引入vld的头文件和库,还要修改代码编译;还要配置参数; |
Windbg工具udmh |
独立于程序之外,不用附加,也不用嵌入,直接通过cmd参数操作进程; |
需要记住命令,检测不准; |
leakDiag |
曲线可视化泄漏,直观方便;可以进行多次获取和查看; |
有时加载不到程序,或者时进程崩溃; |
标签:泄漏,快照,bytes,VLD,dll,内存,四种 From: https://www.cnblogs.com/bclshuai/p/16657677.html