如何解决内存泄露:笨方法手动调试

上篇文章介绍了内存泄露以及避免方法,本篇文章介绍当内存泄露发生时,如何解决

1. 笨方法手动调试

  • 1 检查代码是否每一个new、malloc 都有对应的 delete、free
  • 2 观察有哪些可能分配内存和释放内存的代码,在其上下添加断点,以debug模式运行
  • 3 打开任务管理器,查看调试程序的内存占用,
  • 4 逐个排除:

    - 看运行哪些语句时内存占用增加

    - 看运行释放内存语句后,内存占用是否减少

    - 查看释放后的内存是否仍然存在

  • 5 针对第4步找出内存释放失败的语句,通过查看内存的详细信息,逐步调试

2. 利用工具检测

原文链接:使用_CrtSetDbgFlag检测内存泄露

对于vs启用内存泄露检测:

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

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

注意:

#include必须按照以上所示顺序。如果更改了顺序,所使用的函数可能无法使用。

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

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

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

_CrtDumpMemoryLeaks()

使用示范:

#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>
#definenewnew( _CLIENT_BLOCK, __FILE__, __LINE__)
intmain()
{
int* leak = newint[10];
_CrtDumpMemoryLeaks();
}

这个示范程序与前面讲的多了一个宏定义:

#definenewnew( _CLIENT_BLOCK, __FILE__, __LINE__)

原因稍后再说,我们先看看程序运行(提醒:不要按Ctrl+F5,按F5)后的结果。

程序调试后在“输出”窗口输出如下:

Detected memory leaks!

Dumping objects ->

e:\work\myproject\test\test\test.cpp(57) : {48} client block at 0x00392BB0, subtype 0, 40 bytes long.

Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.

“输出”很明显的告诉了你在test.cpp文件的第57行分配了一个40字节的内存而没有释放。在“输出”窗口中选择包含文件名和行号的行,然后按 F4 键即可进入到源文件中分配内存的行。

现在我们再来看看如果不加之前那个new的宏定义会出现怎么样的结果。

程序调试后在“输出”窗口输出如下:

Detected memory leaks!

Dumping objects ->

{48} normal block at 0x00392BB0, 40 bytes long.

Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD

Object dump complete.

与之前的对比,这次的输出并没有告诉我们这个内存泄露具体是在哪个位置引起的。另外如果没定义#define_CRTDBG_MAP_ALLOC 会引起同样的结果。

时间: 2024-10-28 23:49:46

如何解决内存泄露:笨方法手动调试的相关文章

C#防止内存泄露的方法

一般程序员()都会这样认为:用C#这样的语言编程的一个好处就是无需再考虑内存的分配和释放.你只需创建对象,然后通过一种叫做垃圾收集的机制来处理这 些对象,也就是说:当它们不再被应用程序需要的时候来自动的清除这些对象.这个过程意味着C#解决了其它语言中极难处理的问题──可怕的内存泄露.真的是 这样吗?      其实不然,让我们先了解一下垃圾收集的工作原理.垃圾收集器的工作就是寻找那些不再被应用程序需要的对象,当它们不会再被访问或引用的时候清除它们.(一定要注意是在不会再被访问或引用的时候才清除它

C++内存泄露检查方法

重载全局new 可以写多个版本的new,却只有一个delete: 重载全局new会发生一些不匹配的串扰,尤其是有第三方库的情况下: 我的解决办法 重载单个class的new: 原始类型不能重载,那就使用类似于malloc的办法分配: 我的cfan开源库实现了这个方法 操作系统hook机制 http://my.oschina.net/chunquedong/blog/271248 这些都不跨平台,使用也不方便: valgrind等工具 不跨平台: 除非能实现持续集成,否则很难及时反馈: 有时候引起

C# HttpBrowser 跨进程访问,解决内存泄露问题

1 #undef DEBUG 2 using Microsoft.Win32; 3 using Newtonsoft.Json; 4 using System; 5 using System.Collections.Generic; 6 using System.Collections.Specialized; 7 using System.Diagnostics; 8 using System.Diagnostics.Contracts; 9 using System.Drawing; 10

WebView 避免内存泄露的方法

最近遇到一个Webview内存泄露的问题,上网查了一些结果,在此记录一下: webview在android系统中属于一个比较特殊的view,在调用 webview.destroy()的时候,必须确保webview已经从view tree中被删除,否则这个函数不会执行的.如本app中的用法,在xml中静态定义的webview,只有在整个view退出后调用 webview.destroy()才会被正确执行,但整个view退出后又找不到webview了,这个是很矛盾的. 所以android给出的解决方

pomelo内存泄露排查方法

工具: node-inspector pomelo-cli chrome 步骤 通过pomelo-cli中的dump memory,导出当前服务器的内存堆栈文件:dump1.heapsnapshot. 服务器运行指定模块一段时间后,导出堆栈文件:dump2.heapsnapshot. 用chrome 读取堆栈文件:打开开发者工具->Profiles->Load->选择堆栈文件.先load 前面的dump1,再Load dump2. 在Profiles的左侧会有份文件列表,重点看两份的差异

UIWebView内存泄露问题解决方法

1.在收到内存警告的时候,清除缓存内容. - (void)applicationDidReceiveMemoryWarning:(UIApplication*)application {     [[NSURLCache sharedURLCache] removeAllCachedResponses]; } 2.释放UIWebView的时候 _webView.delegate = nil; [_webView loadHTMLString:@"" baseURL:nil]; [_we

VS 查看是否有内存泄露的方法

加入下列宏定义: [cpp] view plain copy #ifdef _DEBUG #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) #else #define DEBUG_CLIENTBLOCK #endif #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #ifdef _DEBUG #define new D

【转】使用Xcode和Instruments调试解决iOS内存泄露

转自:http://blog.csdn.net/totogo2010/article/details/8233565 虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是可能存在.所以了解原理很重要. 这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled设置的使用. 本文假设你已经比较熟悉Obj-C的内存管理机制. 实验的开发环境:XCode 4.5.2 1.运行Demo. 先下载一个实现准备好的内

使用Xcode和Instruments调试解决iOS内存泄露【转】

转载自:http://blog.csdn.net/totogo2010/article/details/8233565 虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是可能存在.所以了解原理很重要. 这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled设置的使用. 本文假设你已经比较熟悉Obj-C的内存管理机制. 实验的开发环境:XCode 4.5.2 1.运行Demo. 先下载一个实现准备好的