欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

监测内存泄漏问题的工具

程序员文章站 2022-07-14 18:34:43
...

检测内存泄漏的常用方法有如下几种:

一、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系统下开发应用程序时用于调试内存问题的有效工具。它尤其擅长发现内存管理的问题,检查发现程序运行时的内存泄漏。

相关标签: 内存泄露