windows应用进程中堆泄漏检测的简单分析和补充

一般来说,当一个应用进程存在存在内存泄漏的时候,可采用微软推荐的标准方法来进行检查。

当然,这个方法只适用于运行期库的标准堆,进程创建的私有堆不能用此方法来检测,这种情况我们暂时不考虑。


先大概说一下微软推荐的检测方法。


检测内存泄漏的主要工具是调试器和 C 运行时库 (CRT) 调试堆函数。若要启用调试堆函数,请在程序中包括以下语句:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

通过包括 crtdbg.h,将 malloc 和 free 函数映射到其“Debug”版本 _malloc_dbg 和 _free_dbg,这些函数将跟踪内存分配和释放。此映射只在调试版本(在其中定义了 _DEBUG)中发生。发布版本使用普通的 malloc 和 free 函数。

#define 语句将 CRT 堆函数的基版本映射到对应的“Debug”版本。并非绝对需要该语句,但如果没有该语句,内存泄漏转储包含的有用信息将较少。

在添加了上面所示语句之后,可以通过在程序中包括以下语句来转储内存泄漏信息:

_CrtDumpMemoryLeaks();

这样,在调试输出区就能看到堆泄漏检测的内容了,而且里面还包含了源代码信息,极大的方便了调试工作。


微软又提到:

如果程序总是在同一位置退出,调用 _CrtDumpMemoryLeaks 将非常容易。如果程序从多个位置退出,则无需在每个可能退出的位置放置对 _CrtDumpMemoryLeaks 的调用,而可以在程序开始处包含以下调用:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

这样,只有在入口函数退出之后,运行期库进行最后的清理工作结束之前,_CrtDumpMemoryLeaks才会被真正调用,你将有机会把自己创建的全局对象所占用的内存释放掉,避免这些内存被统计到未释放的堆当中。


需要注意的是,前面的头文件包含应该被源代码中的每个模块所引用,未引用的模块的堆信息在输出的时候将无法被识别,所以你最好将这个头文件包含放在类似afxstd.h的预包含文件中,以保证所有模块都能引用到这组头文件信息。


另外 ,可以把输出信息重定向到比如磁盘的文件中,方法是调用这个函数:_CrtSetReportMode。


现在再介绍在实际应用中发现的问题,上面的步骤可以解决你自己的程序的堆泄漏问题,但如果你的可执行程序引用了其他库,静态的或者是动态的,如果这些库中也存在堆泄漏,那么你是看不到源代码信息的,只能看到原始信息!


下面只说静态库且有源代码的情况,这时候,你可以在这个静态库的源代码的每个模块中加入上面提到的语句:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

这样,你在调试输出中就能看到源代码信息了,至于动态库的问题在后续中再分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值