上周从周五开始疯狂修仙,累的一批。
周日正美滋滋的睡着回笼觉,准备补回觉,突然被一个电话打过来去公司查软件内存泄漏问题(连续查了两天)。
当时软件的情况是24 小时内存增加600mb内存,而验收标准是连续跑24 * 7小时,所以对于32位程序来说将达到4.2GB
会出现内存无法分配的情况(超出32位指针访问地址的上限)。
分析问题使用的方法有两种:
一、第一阶段
目测法:
通过注释部分模块,加速运行的方法,查看任务管理器,有无内存泄漏。
时间:1天
结果:不能查找出,感觉很多模块都没有泄露,又都有略微增长。
二、第二阶段
时间:1天
工具法:使用内存泄漏检测工具
使用了的工具有:VLD(Visual Leak Detector),tMemoryMonitor,WinDbg
其中WinDbg是在运行中抓取前后两次内存数据,然后对内存数据进行对比的方式,对抓取的时间节点很考究。
VLD和tMemoryMonitor都是运行结束后再进行生成泄漏报告的方式
VLD需要修改源代码,增加头文件(可以支持Debug版和Release版),会大大降低程序运行的速度。
tMemoryMonitor只支持Release版,且对性能影响较小
三、工具使用方法
1、tMemoryMonitor使用最简单,下载地址: http://wetest.qq.com/cloud/index.php/index/TMM
(1)启动TMM
(2)添加目标程序
(3)启动目标程序并退出
(4)页面查看结果
2、VLD(支持VS 2008-2015)下载地址:https://kinddragon.github.io/vld/
安装后
通常在main函数所在的CPP文件中(任意CPP也可以)include<vld.h>即可
运行程序,退出后产生检测报告
注意事项:
(1)如果有include"stdafx.h",则include <vld.h>放在其后,否则放在最前面
(2)如果想将产生的日志保存到文件中,需要将vld.ini(VLD安装目录下)复制到可执行文件目录下,
ReportFile =.\memory_leak_report.txt
ReportTo = both
(3) 为了减少日志数量将重复泄漏选项日志合并,该默认值false为ture
(4)默认情况下只会检测主程序的模块,要想增加其他模块的内存泄露检测,需要配置vld.ini文件中的ForceIncludeModules,多个模块用";"分隔,如: ForceIncludeModules = test.dll;test2.dll
(5)如果需要在release下进行检查,需要把Debug版中VS工程的配置复制到Release版中(include目录和链接库目录以及链接库名称VLD.lib),同时在main函数中增加如下代码:
#define VLD_FORCE_ENABLE // 增加该宏定义
int main()
{
VLDGlobalEnable();
VLDReportLeaks();
//user code start...
//......
//user code end
VLDGlobalDisable();
}
四、结果
通过上述各种手段和方式查询
发现内存泄漏的原因如下:
#include <list>
struct Vecotr
{
Vecotr()
{
e = new double[3];
}
~Vecotr()
{
delete [] e;
}
double* e;
};
void Test()
{
std::list<void *> list_;
for (int i = 0; i < 10; i++)
{
list_.push_back(new Vecotr());
}
for (auto iter : list_)
{
delete iter;
}
list_.clear();
}
类似上述代码,定义了一个void *的指针容器,加入了一些数据Vecotor指针
当delete void *指针时,不会执行Vecotor的析构函数
从而造成内存泄漏
来源:CSDN
作者:三体问题
链接:https://blog.csdn.net/q943520218/article/details/103585684