监测内存泄漏问题的工具
检测内存泄漏的常用方法有如下几种:
一、MS C-Runtime Library内建的检测功能
MFC应用在Debug模式下编译执行,程序运行结束后,Visual C++会输出内存的使用情况,如果发生内存泄漏,在Debug窗口中会输出所有发生泄漏的内存块信息,这是因为IDE自动加入了内存泄漏的检测代码,MFC在程序执行过程中维护了一个内存链,以便跟踪每一块内存的生命周期。在程序退出时,dbgheap.c文件中extern "C" _CRTIMP int__cdecl_CrtDumpMemoryLeaks(void)
函数被调用,遍历当前的内存链,如果发现存在没有释放的内存,则打印出内存泄漏的信息。
要在非MFC程序中打开内存泄漏的检测功能,需要在程序的入口处添加一下代码:
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF));
这样,在程序运行结束时,如果还有内存块没有释放,它们的信息就会被打印到Debug窗口里,如下代码片段所示:
#include<crtdbg.h>
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
void EnableMemLeakCheck()
{
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF));
}
int main()
{
EnableMemLeakCheck();
_CrtSetBreakAlloc(53); // 在指定的对象分配序号上设置断点
int* pLeak = new int[10];
return 0;
}
二、外挂式的检测工具
外挂式的检测工具有BoundsChecker或Insure++。
BoundsChecker采用的是CodeInjection的技术,截获对分配内存和释放内存的函数的调用。简单地说,当程序运行时,BoundsChecker的DLL被自动载入进程的地址空间中,然后它会修改进程中对内存分配和释放的函数调用,让这些调用首先转入它的代码,然后再执行原来的代码(这样无须修改被调试程序的源代码或工程配置文件)。
而Insure++则是利用其专利技术(源码插装和运行时指针跟踪)来发现大量的内存操作错误,准确报告错误源代码和执行轨迹。
注意:BoundsChecker或Insure++对于linux开发环境无能为力。
Linux下的外挂式检测工具有Rational Purify或Valgrind
Rational Purify主要是针对软件开发过程中难以发现的内存错误、运行时错误。它可以在软件开发过程中自动地发现错误,准确地定位错误,并提供完备的错误信息,从而减少调试时间。同时也是市场上唯一支持多平台的相关工具,并且可以和很多主流开发工具集成。Purify可以检查应用的每一个模块,甚至可以查出复杂的多线程或者进程应用中的错误。另外,它不仅可以检查C/C++,还可以对Java或.NET中的内存泄漏问题给出报告。
在linux中,使用Purify非常简单,只须重新编译程序: purify g++ -g main.cpp -o LeakDetector
运行编译生成的可执行文件LeakDetector,就可以定位出内存泄漏的具体位置。
除了Rational Purify,Valgrind也是Linux系统下开发应用程序时用于调试内存问题的有效工具。它尤其擅长发现内存管理的问题,检查发现程序运行时的内存泄漏。
上一篇: Android Handler内存泄露