首页 > 系统相关 >四种内存泄漏方法总结和比较

四种内存泄漏方法总结和比较

时间:2022-09-05 13:44:24浏览次数:70  
标签:泄漏 快照 bytes VLD dll 内存 四种

 

关注: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

相关文章

  • hi3516开机修改内存和MMZ分配并安装SDK驱动
    1. 拿到的开发版中已经安装最小系统,连接串口开机,设置启动文件#配置IP地址ifconfigeth0172.16.96.151netmask255.255.248.0routeadddefaultgw172.16.100.1#......
  • *第十二章 内存管理
                                  ......
  • 内存管理——缓存一致性问题
    缓存一致性问题问题1:多核CPU与cache的缓存一致性问题多核CPU在访问内存时,每个核都有自己的cache,由于cache的写回机制,部分数据没有及时更新到内存,那么在不同线程访问同一......
  • 并发学习记录09:共享模型之内存
    Java内存模型JMM指的是Javamemorymodel,它定义了主存,工作内存等抽象概念,相当于做一个隔离层,将底层CPU寄存器,缓存,硬件内存,CPU指令优化提供的功能通过一个简单接口给使用......
  • Spring创建bean的四种方式
    获取bean对象代码: ApplicationContextapp=newClassPathXmlApplicationContext("applicationContext.xml"); app.getBean("userDao");----通过配置文件里bean的id值获得b......
  • Linux下查看系统中占用内存和CPU最多的进程
    Linux下查看系统中占用内存和CPU最多的进程前一段时间参加面试,被问到一个场景题:就比如说我们发现一台Linux的服务器,它的一些系统资源,比如说CPU内存都涨得比较厉害的。......
  • 斯特林数的四种求法
    有一回对我说道,“你读过书么?”我略略点一点头。他说,“读过书,……我便考你一考。组合数学里的斯特林数,怎样说的?”我想,AKIOI的人,我也配答么?便回过脸去,不再理会。田乙己等了许......
  • 稻盛和夫:这四种“法”,是人生最好的修炼
    四本书的出版顺序是:《活法》《干法》《心》《成法》https://baijiahao.baidu.com/s?id=1719812212580896527&wfr=spider&for=pc......
  • java 内存模型之 volatile 核心原理与应用
    1.happens-before规则https://blog.csdn.net/qq_39935047/article/details/1203847992.Juc12_Volatile的可见性、不保证可见性、有序性、使用、内存屏障四大指令StoreSt......
  • pod中进行vi操作导致内存异常触发重启
    前天应用反馈说有个集群的访问异常抖动,于是查看了一下配置。发现pod异常重启了。于是怀疑是jmv异常,于是在pod中查看相关的日志。结果又重启了2次。于是对这二次进行分析......