当前位置:文档之家› 几个内存泄漏的例子

几个内存泄漏的例子

几个内存泄漏的例子
几个内存泄漏的例子

几个内存泄漏的例子

?new和delete要成对使用

?new和delete要匹配

经常看到一些C++方面的书籍中这样提及到内存泄漏问题,这样的说法的意思是比较明白,但对于初学C++程序员还是很难掌握,所以下面举几个反面的例子,希望对大家有帮助。

例一:错误处理流程中的return导致的内存泄漏

bool MyFun()

{

CMyObject* pObj = NULL;

pObj = new CMyObject();

if (…)

return false;

if(…)

return false;

if (pObj != NULL)

delete pObj;

return true;

}

注意:红色字体部分的return之前没有释放pObj,导致内存泄漏。

例二:exception改变了程序的正常流程,导致内存泄漏

情况1:

HRESULT MyFun()

{

HRESULT hr = S_OK;

try

{

CMyObject* pObj = NULL;

pObj = new CMyObject();

if (…)

{

hr = E_FAIL;

throw hr;

}

if(…)

{

hr = E_FAIL;

throw hr;

}

if (pObj != NULL)

delete pObj;

}

catch (HRESULT& eHr)

{

}

return hr;

}

情况2:

void OtherFun() // 可能是自己写的其他函数;

// 也可能是其他人写的函数;

// 也可能是系统的API;

{

if(…)

throw exception;

}

bool MyFun()

{

CMyObject* pObj = NULL;

pObj = new CMyObject();

OtherFun();

if (pObj != NULL)

delete pObj;

return true;

}

注意:上面的两种情况中的throw行为将导致程序的正常流程,一旦有throw的动作发生,pObj对象将不会被正确释放(delete)。

例三:忘记释放系统API创建的资源,导致内存泄露

bool CMyClass::MyFun()

{

HANDLE hHandle = CreateEvent(NULL,FALSE,TRUE,NULL);

if (…)

return false;

return true;

}

注意:系统API CreateEvent创建的HANDLE对象,需要自己释放,否则会导致内存泄漏。还有其他一些系统的API也是如此,如:CreateFile、CreateFileMapping 等等,所以我们在使用不熟悉的系统API时,一定要仔细阅读MSDN。

例四:PostMessage可能导致的内存泄漏

// 自定义的消息结构体

typedef struct tagMSG

{

int i;

float f;

}MSG;

// 发送消息的函数

void MyFun()

{

MSG* pMsg = new MSG;

PostMessage(m_hWnd, WM_MYEVENT, (WPARAM)pMsg, 0);

}

// 接收消息的函数

afx_msg void OnMessage(WPARAM wParam, LPARAM lParam)

{

MSG* pMsg = (MSG*)wParam;

m_i = pMsg->i;

m_f = pMsg->f;

}

注意:OnMessage函数中忘记释放pMsg,导致内存泄漏。

例五:函数返回new的对象而导致的内存泄漏

char* MyFun()

{

char* p = new char[10];

return p;

}

注意:调用MyFun程序的人可能不会注意到MyFun函数内部new出的对象,往往会忽略对象p的释放。

例六:不好的类结构也会导致内存泄漏

// MyClass.h文件

class MyClass

{

public:

MyClass();

virtual ~MyClass();

BOOL Init();

BOOL UnInit();

private:

char* m_pStr;

}

// MyClass.cpp文件MyClass::MyClass()

: m_pStr(NULL)

{

}

MyClass::~MyClass()

{

}

BOOL MyClass::Init()

{

m_pStr = new char[100];

if (…)

{

delete m_pStr;

m_pStr = NULL;

return FALSE;

}

return TRUE;

}

BOOL MyClass::UnInit()

{

if (m_pStr != NULL)

{

delete m_pStr;

m_pStr = NULL;

}

return TRUE;

}

注意:这个类在Init()函数中new出类资源,需要调用相应的UnInit()函数来释放资源,但有些时候这个类需要给其他人使用,别人在使用时可能会忘记调用UnInit()函数来释放资源,这样就造成了内存泄漏,为了防止这个问题发生,最好在MyClass::~MyClass()函数中也进行资源释放。如下写法:

MyClass::~MyClass()

{

UnInit();

}

例七:容易忽视的深层次结构对象的内存泄漏

typedef struct MyStruct

{

int i;

BSTR bstr;

}

void MyFun(OLECHAR * sz)

{

MyStruct* pStru = new MyStruct;

pStru->bstr = SysAllocString(sz);

delete pStru;

}

注意:pStru是个深层次结构的对象,在这个对象内部还有指针数据类型bstr,在释放pStr时,如果忘记了释放其内部的指针对象bstr,也会导致内存泄漏。当然这个例子比较简单,在我们实际编程时,深层次结构的对象要比这个复杂的多,所以处理这些对象时需要格外小心。

例八:虚基类的析构函数可能导致的问题

///////////////////////////

// Base.h

class Base

{

public:

Base();

~Base();

virtual void TestFun();

}

// Base.cpp

Base::Base()

{

}

Base::~Base()

{

if (m_pStr != NULL)

{

delete m_pStr;

}

}

void Base::TestFun()

{

}

////////////////////////////// // MyClass.h

class MyClass : public Base {

public:

MyClass();

~MyClass();

virtual void TestFun(); protected:

char* m_pStr;

}

// MyClass.cpp

MyClass::MyClass()

: m_pStr(NULL)

{

}

MyClass::~MyClass()

{

if (m_pStr != NULL)

delete m_pStr;

}

void MyClass::TestFun()

{

m_pStr = new char[100];

}

/////////////////////////////

// Test.cpp

int _tmain(int argc, _TCHAR* argv[])

{

Base* pClass = new CMyClass();

pClass->TestFun();

delete pClass;

return 0;

}

注意:由于Base类的析构函数不是virtual类型,在_tmain程序的用法中,将会导致CMyClass的析构不会被调用,引起内存泄漏。

总结:

1、C++编程中,内存泄漏是个比较烦人的问题,创建(new)对象的“入口”一般

只有一处,但需要释放(delete)对象的“出口”却很多,而且由于创建(new)出来的对象的生存周期不固定,所以要完全避免内存泄漏是比较困难,需要我

们在编程时格外小心;

2、养成良好的代码书写习惯,尽量在编写代码时解决内存泄漏问题;

3、一旦程序中发生内存泄漏时,可以使用一些内存泄漏检查工具(如:Bound Check

等)来查找,这些工具可以帮助我们找出部分的内存泄漏的代码;

4、有些内存泄漏的问题还需要我们手工查找,检查代码的逻辑也是查找内存泄漏

的一种有效手段。

Android开发内存泄漏及检查工具使用培训资料

Android 开发内存泄漏及检查工具使用培 训资料

目录 1内存泄露 (3) 1.1 内存泄露的概念 (3) 1.2 开发人员注意事项 (4) 1.3 Android(java)中常见的引起内存泄露的代码示例 (4) 1.3.1查询数据库没有关闭游标 (6) 1.3.2 构造Adapter时,没有使用缓存的convertView (6) 1.3.3 Bitmap对象不在使用时调用recycle()释放内存 (7) 1.3.4 释放对象的引用 (8) 1.3.5 其他 (9) 2内存泄露的分析工具 (9) 2.1 内存监测工具DDMS --> Heap (9) 2.2 内存分析工具MAT (Memory Analyzer Tool) (10) 2.2.1 生成.hprof文件 (10) 2.2.2 使用MA T导入.hprof文件 (11) 2.2.3 使用MA T的视图工具分析内存 (12)

1内存泄露 Android 应用程序开发以Java语言为主,而Java编程中一个非常重要但却经常被忽视的问题就是内存使用的问题。Java的垃圾回收机制(Garbage Collection 以下简称GC)使得很多开发者并不关心内存使用的生命周期,只顾着申请内存,却不手动释放废弃的内存,而造成内存泄露,引起很多问题,甚至程序崩溃。Android的虚拟机Dalvik VM和java虚拟机JVM没有什么太大的区别,只是在字节码上稍做优化,所以Android应用开发中同样会出现内存泄露的问题。而且由于Android智能平台主要用于嵌入式产品开发,可用的内存资源更加稀少,所以对于我们Android应用开发人员来说,就更该了解Android程序的内存管理机制,避免内存泄露的发生。 1.1 内存泄露的概念 在计算机科学中,内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏与许多其他问题有着相似的症状,并且通常情况下只能由那些可以获得程序源代码的程序员才可以分析出来。然而,有不少人习惯于把任何不需要的内存使用的增加描述为内存泄漏,严格意义上来说这是不准确的。 一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显式释放的内存。应用程序一般使用malloc,calloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。 这里我们只简单的理解,在java程序中,如果已经不再使用一个对象,但是仍然有引用指向它,GC就无法收回它,当然该对象占用的内存就无法再被使用,这就造成内存泄露。可能一个实例对象的内存泄露很小,并不会引起很大的问题。但是如果程序反复做此操作或者长期运行,造成内存不断泄露,终究会使程序无内存可用,只好被系统kill掉。在以下情况,内存泄漏导致较严重的后果: * 程序运行后置之不理,并且随着时间的流失消耗越来越多的内存(比如服务器上的后台任务,尤其是嵌入式系统中的后台任务,这些任务可能被运行后很多年内都置之不理); * 新的内存被频繁地分配,比如当显示电脑游戏或动画视频画面时; * 程序能够请求未被释放的内存(比如共享内存),甚至是在程序终止的时候; * 泄漏在操作系统内部发生; * 泄漏在系统关键驱动中发生; * 内存非常有限,比如在嵌入式系统或便携设备中; * 当运行于一个终止时内存并不自动释放的操作系统(比如AmigaOS)之上,而且一旦丢失只能通过重启来恢复。

内存泄漏检查

内存泄漏检测方法 ?对于不同的程序可以使用不同的方法来进行内存泄漏的检查,还可以使用一些专门的工具来进行内存问题的检查,例如MemProof、AQTime、Purify、BundsChecker 等。 ?也可以使用简单的办法:利用Windows自带的Perfmon来监控程序进程的handle count、Virtual Bytes和Working Set 3个计数器。 Handle Count记录了进程当前打开的句柄个数,监视这个计数器有助于发现程序是否存在句柄类型的内存泄漏; Virtual Bytes记录了程序进程在虚拟地址空间上使用的虚拟内存的大小,Virtual Bytes一般总大于程序的Working Set,监视Virtual Bytes可以帮助发现一些系统底层的问题; Working Set记录了操作系统为程序进程分配的内存总量,如果这个值不断地持续增加,而Virtual Bytes却跳跃式地增加,则很可能存在内存泄漏问题。 堆栈内存泄漏 ?堆栈空间不足会导致在受托管的情况下引发StackOverflowException类型的异常,线程泄漏是堆栈内存泄漏的其中一种。线程发生泄漏,从而使线程的整个堆栈发生泄漏。 ?如果应用程序为了执行后台工作而创建了大量的工作线程,但却没有正常终止这些线程,则可能会引起线程泄漏。 一个堆栈内存泄漏的例子: private void button1_Click(object sender, EventArgs e) { // 循环启动多个线程 for (int i = 0; i < 1500; i++) { Thread t = new Thread(new ThreadStart(ThreadProc)); t.Start(); } } static void ThreadProc() { Console.WriteLine("启动Thread #{0}

几个内存泄漏的例子

几个内存泄漏的例子 ?new和delete要成对使用 ?new和delete要匹配 经常看到一些C++方面的书籍中这样提及到内存泄漏问题,这样的说法的意思是比较明白,但对于初学C++程序员还是很难掌握,所以下面举几个反面的例子,希望对大家有帮助。 例一:错误处理流程中的return导致的内存泄漏 bool MyFun() { CMyObject* pObj = NULL; pObj = new CMyObject(); … if (…) return false; … if(…) return false; … if (pObj != NULL) delete pObj; return true; } 注意:红色字体部分的return之前没有释放pObj,导致内存泄漏。 例二:exception改变了程序的正常流程,导致内存泄漏 情况1: HRESULT MyFun() { HRESULT hr = S_OK; try { CMyObject* pObj = NULL; pObj = new CMyObject(); … if (…) { hr = E_FAIL; throw hr; } … if(…) {

hr = E_FAIL; throw hr; } … if (pObj != NULL) delete pObj; } catch (HRESULT& eHr) { } return hr; } 情况2: void OtherFun() // 可能是自己写的其他函数; // 也可能是其他人写的函数; // 也可能是系统的API; { … if(…) throw exception; … } bool MyFun() { CMyObject* pObj = NULL; pObj = new CMyObject(); … OtherFun(); … if (pObj != NULL) delete pObj; return true; } 注意:上面的两种情况中的throw行为将导致程序的正常流程,一旦有throw的动作发生,pObj对象将不会被正确释放(delete)。 例三:忘记释放系统API创建的资源,导致内存泄露 bool CMyClass::MyFun() { HANDLE hHandle = CreateEvent(NULL,FALSE,TRUE,NULL); … if (…)

内存泄露测试方法

如何测试客户端软件的内存泄露客户端软件包括C/S系统的客户端和B/S系统中的客户端控件,当用户使用客户端软件时,如果发现我们的软件会吃内存,那是很丢面子的事,有哪些好的测试方法呢?希望大家能踊跃提出自己的看法。 会员huior的精彩回答:如何发现客户端软件中的内存泄露?我的看法是:检测内存泄漏的问题应该尽早进行,它绝不应该是系统测试时的主要目标。也就是说,检查是否存在内存泄漏,应该从编码时就要考虑,单元测试和集成测试时要重点检查。如果前期没有考虑,等到了系统测试才想起检查或者才发现泄漏,为时已晚,此时再去定位泄漏的位置,太难太难了,它可能会让你的交付日期delay不确定的时间。 最近看了一些自动错误预防(AEP)的理论,我深受启发。作为测试人员的我们,从“发现错误”转变到“帮助开发人员预防错误”,这将是一个巨大的转变。所以说,下面我的答案中的第一点,我先说如何预防内存泄漏的问题,然后再讲如何发现。如何在开发过程中有效预防内存泄漏? 第一步:遵循“好”的编程规则“好”的编程规则是各位前辈经验和教训的集合,好的编程规则堪称开发者的“圣经”。遵循统一的编程规则,可以让开发新手少走好多弯路,可以让项目整体的质量维持一个起码的“质量底线”。有关内存泄漏方面的规则主要是“内存管理”方面的,举几个简单的,如下x用malloc或new申请内存之后,立即检查指针值是否为NULL(防止使用指针值为NULL的内存),×动态内存的申请与释放是否配对(防止内存泄漏),x malloc 语句是否正确无误?例如字节数是否正确?类型转换是否正确×是否出现野指针,例如用free或delete释放了内存之后,忘记将指针设置为NULL。 第二步:积极主动检测“内存泄漏”,严格遵循好的编程规则,可以让程序员在代码中尽量少的引入bug,但一旦不小心引入了,怎么办?这就要求我们在单元测试和集成测试中严格把关。在这个阶段,单靠程序员或者测试员通过“代码走查”的方式检查内存泄漏,客户的实践和我的经验告诉我,这是不切实际的,无论效率还是时间。如果能够借助于一些专业的工具的话,情况可能就不一样了。 如果你的程序是用Visual C++ 6.0开发,那么Numega的BoundsChecker将是你检测“内存泄漏”最好的选择,如果是Visual C++.NET,可以试一下Compuware的DevPartner。如果你的程序基于Unix或者Linux平台,使用C或者C++,可以考虑一下开源的工具valgrind,我的朋友跟我说,它在一定程度上比Rational的Purify更出色。上面的工具都要求程序能够动态运行起来,而且测试用例需要你自己准备。 如果你正处于单元测试或集成测试阶段,程序代码量已经足够大,而且还不能够动态运行,要尽早检测代码中的“内存泄漏”问题,该怎么办?此时你可以试用一下目前最新的静态分析技术:×它不要求代码能够动态运行,×也不需要你来编写测试用例,×只需要代码能够正常编译,就可以发现代码只有在执行过程中才出现的错误,当然也包括内存泄漏。 这方面的工具有Klocwork的K7,Coverity的SQS,以及C++test中的BugDetective,其中最“物美价廉”的就是c++test的BugDetective。 如何发现客户端软件的“内存泄漏”?如果开发过程中已经按照我上面提到的去做,相信发布后的程序存在“内存泄漏”的可能性几乎为零。如果开发过程已经到了后期,系统测试已经开始做了,还要发现内存泄漏,这个时候我希望你能够拿到源代码。如果有源代码,你还可以考虑第二步,借助专业的工具协助,虽然可能效果不一定特别理想,但总比下面我提到的方法更好一些。 当然作为测试人员,通常会碰到“需要在系统测试阶段检测是否有内存泄漏,而且没有

使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)

使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践) 文章分类:.net编程 关键字: memory leak, .net, .net memory profiler, https://www.doczj.com/doc/1c6843104.html, 做过应用诊断与优化的朋友都知道内存泄漏和带来的危害,对这种情况的分析和定位一般会比较困难,尤其在 .NET/Java 应用中,隐式的堆内存管理以及托管对象间纷繁复杂的引用关系,使分析和定位问题更加复杂。本文以我的了解,尽量说明了: 1.一种对 .NET/Java 托管内存类应用的内存泄漏分析和诊断方法; 2.使用 .Net Memory Profiler 工具对一个真实 https://www.doczj.com/doc/1c6843104.html, 应用中存在内存 泄漏问题的分析、诊断实践过程作为示例。 本文包括以下问题、不足: 1.本文以我的现有理解写成,尤其是“方法”相关的内容,每个人在不同情 况下会有不同的方式; 2.不是 .Net Memory Profiler 工具的全面讲解,实践中所涉及的功能仅是 为了定位这里 https://www.doczj.com/doc/1c6843104.html, 应用中的问题。可参见 .Net Memory Profiler 文档 。 .NET/Java 托管内存类应用的内存泄漏分析和诊断 方法 首先是些科普知识,理解的兄弟请自行快速跳过。 在托管内存管理中,“泄漏”意义不同与传统 Native 应用中的忘记显式释放(delete/delete[] 等)不同,当然对于非托管资源之类(如句柄等)还是需要在 Finalize (析构方法等同于 Finalize)方法中显式释放的,在托管内存管理中“泄漏”对象实例指的是,由于与 Root 对象集中的对象存在本应断开的引用关系,而让 GC 线程认为该对象还被使用,因而不能被释放,尽管其不再会被使用。决大部分情况下,由于应用(程序员)认为该对象不会存在了,而在再次使用时,又在托管堆中再次创建了该对象实例,可以想象这样的

VS2005内存泄漏检测方法

VS2005内存泄漏检测方法 2010-03-09 09:13 247人阅读评论(0) 收藏举报VS2005内存泄漏检测方法 非MFC程序可以用以下方法检测内存泄露: 1.程序开始包含如下定义: view plaincopy to clipboardprint? 1. #ifdef _DEBUG 2. #define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) 3. #else 4. #define DEBUG_CLIENTBLOCK 5. #endif // _DEBUG 6. #define _CRTDBG_MAP_ALLOC 7. #include 8. #include 9. #ifdef _DEBUG 10. #define new DEBUG_CLIENTBLOCK 11. #endif // _DEBUG

2.程序中添加下面的函数: view plaincopy to clipboardprint? 1. _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);

1. #ifdef _DEBUG 2. protected: 3. CMemoryState m_msOld, m_msNew, m_msDiff; 4. #endif // _DEBUG 1. #ifdef _DEBUG 2. m_msOld.Checkpoint(); 3. #endif // _DEBUG 4. 5.

java内存泄露、溢出检查方法和工具

JAVA内存泄露、溢出的检查方法、工具介绍 问题发现: 在我们运行的一个项目上线运营后发现运行两天左右就会报内存溢出,只有重启tomcat才能恢复服务,异常信息如下: https://www.doczj.com/doc/1c6843104.html,ng.OutOfMemoryError: GC overhead limit exceeded https://www.doczj.com/doc/1c6843104.html,ng.OutOfMemoryError: Java heap space 原因分析: 在此之前必须先介绍一下关于jvm的内存控制,JVM即java虚拟机,它运行时候占用一定的内存,其大小是有限定的,如果程序在运行时jvm占用的内存大于某个限度,则会产生内存溢出,也就是“https://www.doczj.com/doc/1c6843104.html,ng.outofmemoryerror”。如果jvm内存的没有限度,并且有无限大的内存,那jvm就永远不会出现内存溢出了。很明显无限的内存是不现实的,但是一般情况下我们程序运行过程所需要的内存应该是一个基础固定的值,如果仅是因为我们的项目所需内存超过了jvm设置内存值导致内存溢出,那么我们可以通过增大jvm的参数设置来解决内存溢出的问题。详细处理可参考java jvm的如下参数设置:-Xms -Xmx -Xmn -Xss -Xms: 设置JVM初始内存,此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 -Xmx:设置JVM最大可用内存。 -Xmn:设置年轻代大小,整个堆大小=年轻代大小+年老代大小+持久代大小.持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8. -Xss:设置每个线程的堆栈大小.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成。 在jvm参数调试过程中,发现分配最大内存数超过1G后,仍然会产生内存溢出的现象,而估计其正常分配使用的内存应该不会超过1G,那么由此可以基本断定其存在内存泄露现象,也就是一些原来分配的不再使用的内存不能被java的垃圾回归所回收,导致不断占用原分配的内存而不释放,导致不断申请更多的内存直到超过内存设置而导致内存溢出。

vld内存泄露检测工具介绍及基本原理分析

vld介绍及基本原理分析 作者:何锟 目录 内容导读 (2) 一、vld简介 (2) 二、vld使用方法介绍 (2) 使用步骤 (2) 使用举例 (2) 配置文件(vld.ini)说明 (3) 原理分析分析与思考 (4) 关键技术 (4) 流程分析 (4) 钩子程序分析 (5) 优缺点分析与改进 (6) 优缺点: (6) 改进思考 (6)

内容导读 本文分包括这几个部分: 1、Vld简介 2、Vld使用方法介绍 3、vld原理分析分析 4、vld优缺点分析与改进 一、vld简介 vld全称:Visual Leak Detector 发展历史:2005年~ 2016年,Version 2.5.0 版权:免费、开源 用途:检测windows c/c++程序内存泄露,并且输出详细报告 二、vld使用方法介绍 使用步骤 1、集成到工程 在工程任意位置包含头文件”vld.h”、并且指定静态库路径”vld.lib”,编译时需要宏_DEBUG或VLD_FORCE_ENABLE 2、运行程序 运行环境:debughelp.dll, vld.dll,vld.ini 3、执行测试用例 4、关闭程序时生成了内存测试报告(文本文件或IDE输出窗口) 5、根据报告分析内存泄露 使用举例 源码

编译运行后,可以看到IDE的输出窗口中输出内容 注意:报告还可以输出到txt文件,默认名称为memory_leak_report.txt 配置文件(vld.ini)说明 Vld.ini里面有详细的说明。其中常用的选项有: 1:开启或关闭内存测试 2:报告中是否去掉重复的堆栈 3:函数调用栈的最大深度 4:泄露内存打印的字节数

内存泄露检测工具

1. ccmalloc-Linux和Solaris下对C和C++程序的简单的使用内存泄漏和malloc调试库。 2. Dmalloc-Debug Malloc Library. 3. Electric Fence-Linux分发版中由Bruce Perens编写的malloc()调试库。 4. Leaky-Linux下检测内存泄漏的程序。 5. LeakTracer-Linux、Solaris和HP-UX下跟踪和分析C++程序中的内存泄漏。 6. MEMWA TCH-由Johan Lindh编写,是一个开放源代码C语言内存错误检测工具,主要是通过gcc的precessor来进行。 7. V algrind-Debugging and profiling Linux programs, aiming at programs written in C and C++. 8. KCachegrind-A visualization tool for the profiling data generated by Cachegrind and Calltree. 9. Leak Monitor-一个Firefox扩展,能找出跟Firefox相关的泄漏类型。 10. IE Leak Detector (Drip/IE Sieve)-Drip和IE Sieve leak detectors帮助网页开发员提升动态网页性能通过报告可避免的因为IE局限的内存泄漏。 11. Windows Leaks Detector-探测任何Win32应用程序中的任何资源泄漏(内存,句柄等),基于Win API调用钩子。 12. SAP Memory Analyzer-是一款开源的JA V A内存分析软件,可用于辅助查找JA V A程序的内存泄漏,能容易找到大块内存并验证谁在一直占用它,它是基于Eclipse RCP(Rich Client Platform),可以下载RCP的独立版本或者Eclipse的插件。 13. DTrace-即动态跟踪Dynamic Tracing,是一款开源软件,能在Unix类似平台运行,用户能够动态检测操作系统内核和用户进程,以更精确地掌握系统的资源使用状况,提高系统性能,减少支持成本,并进行有效的调节。 14. IBM Rational PurifyPlus-帮助开发人员查明C/C++、托管.NET、Java和VB6代码中的性能和可靠性错误。PurifyPlus 将内存错误和泄漏检测、应用程序性能描述、代码覆盖分析等功能组合在一个单一、完整的工具包中。 15. Parasoft Insure++-针对C/C++应用的运行时错误自动检测工具,它能够自动监测C/C++程序,发现其中存在着的内存破坏、内存泄漏、指针错误和I/O等错误。并通过使用一系列独特的技术(SCI技术和变异测试等),彻底的检查和测试我们的代码,精确定位错误的准确位置并给出详细的诊断信息。能作为Microsoft V isual C++的一个插件运行。

内存泄漏的检测、定位和解决经验总结

内存泄漏的检测、定位和解决经验总结 【摘要】 结合局端MCU项目中CSS、NMS模块内存泄漏检测、修正的过程,简要介绍了内存泄漏检测的工具,提出了内存泄漏检测的一些方法(怎样对程序结构进行改造,怎样对程序进行隔离以易于进行内存泄漏检测)。总结了内存泄漏检测过程中成功和失败的体会,希望能对后来者有所启发。 【关键词】 内存泄漏 一、故障或失误概况 局端MCU项目中CSS(Conference Schedule System)、NMS(NetWork Management System)模块自2.03版本起就有内存泄露的问题,开发NGN版本时也花过大量的精力来争取解决这个问题,虽然也修正了一些内存泄漏,但最终检测工具表面现象显示剩下的内存泄露都是所使用的开发库的代码产生的,于是也就大意的认为是所使用的ACE/TAO库本身有内存泄漏,于是无果而终,使这两个模块的内存泄漏问题一直延续到2.03.20x版本。 由于后续测试部和开发部进行测试时引入了Robot来进行自动测试,使业务操作量巨升,此时CSS 模块的内存泄漏问题就更明显了,从程序启动时的13M内存,经过一两个月后可以飙升到200 M左右,正因为此局端MCU项目好几个程序都采用了看门狗的方式来定时检测程序的状态防止程序当掉。 由于问题比较严重,于是再次进行内存泄漏问题的攻关,测试时NMS模块业务操作量小内存泄漏不明显,于是此次攻关重点是查CSS的内存泄漏问题。 此次再次进行CSS行内存泄露问题的研究,力争解决CSS的内存泄露问题,实在找不到解决方案(例如为所使用的开发库的原因)也定位出具体原因供项目组参考。 二、诊断过程 2.1工具介绍 目前Windows平台上流行的内存泄露检测工具有Rational Purify、BoundsChecker、insure++,由于C SS较复杂又是多线程采用Rational Purify工具程序就启动不起来,无法进行检测;parasoft 公司的insure+ +工具传说中比较好用,但由于我们公司没有相应的licence无法使用;最后选择采用限制版的BoundsChec ker来进行检测。

AQTime进行内存泄露和资源泄漏监控

利用AQTime分析.NET程序内存泄露 1.AQTime简介 AQTime是一款著名的,功能强大的Code Profiler工具,它与TestComplete(自动化测试工具)一样,是同属于AutomatedQA公司旗下的软件测试产品,产品含有完整的性能和内存,资源调试工具集,并支持32位及64位机器上的Windows,.NET和JAVA应用程序,同时还支持VBScript和Jscript 代码调试。 AQTime可以帮助程序员理解程序执行过程中运行情况,它内置了大量的调试方案,以及显示面板帮助调试人员隔离以及消除程序的性能问题以及内存、资源泄漏问题,AQTime即可以作为单独的程序启动也可以集成到Microsoft Visual Studio或者Embarcadero RAD Studio(Delphi和C++ Builder的集成开发环境)运行. AQTime的主要功能 ●性能测试 ●内存使用情况监控 ●系统资源使用情况监控 ●代码覆盖率监控 ●兼容性分析 ●程序异常,模块加载,函数调用情况监控 AQTime内置有丰富的调试方案,分为5类(Allocation、Coverage、Performance、Static Analysis、Tracing),共14种调试方案工具集,列举如下: ●Performance Profiler 性能调试方案 提供针对程序中任意范围内的程序段或单行代码进行的性能检测。在程序执行期间,工具自动收集运行时的性能表征数据(如调用次数、执行时间、调用与被调用函数、函数调用层次图、执行期间发生的异常情况等等)。此外,工具提供与运行时间、CPU缓存使用等相关的多种计数器[如Elapsed Time、User Time、User+Kernel Time、CPU Cache Misses、Context Switches等],为了解应用代码级和应用程序级上的性能使用和确定可能存在的性能瓶颈提供详实的参考数据。 ●Allocation Profiler 内存使用分析方案 跟踪程序执行过程中对内存资源的使用情况,按类、对象检测并显示程序中对内存资源的使用情况,确定明确或潜在的内存泄漏来源,避免由此造成的程序问题。

Java程序里的内存泄漏是如何表现的

Java程序里的内存泄漏是如何表现的 大多数程序员都知道使用类似于Java 的编程语言的好处之一就是他们无需再为内存的分配和释放所担心了。你只需要简单地创建对象,当它们不再为程序所需要时Java 会自行通过一个被称为垃圾收集的机制将其移除。这个过程意味着Java 已经解决了困扰其他编程语言的一个棘手的问题-- 可怕的内存泄漏。果真是这样的吗? 在进行深入讨论之前,让我们先回顾一下垃圾收集是如何进行实际工作的。垃圾收集器的工作就是找到程序不再需要的对象并在当它们不再被访问或引用时将它们移除掉。垃圾收集器从贯穿整个程序生命周期的类这个根节点开始,扫描所有引用到的节点。在遍历节点时,它跟踪那些被活跃引用着的对象。那些不再被引用的对象就满足了垃圾回收的条件。当这些对象被移除时被它们占用的内存资源会交还给Java 虚拟机(JVM)。 因此Java 代码的确不需要程序员负责内存管理的清理工作,它自行对不再使用的对象进行垃圾收集。然而,需要记住的是,垃圾收集的关键在于一个对象在不再被引用时才被统计为不再使用。下图对这一概念进行了说明。 上图表示在一个Java 程序执行时具有不同的生命周期的两个类。类A 首先被实例化,它存在的时间比较长,几乎贯穿整个进程的生命周期。在某个时间点,类B 被创建,类A 添加了一个对这个新建类的引用。我们假设类B 是某个用于显示并返回用户指令的用户界面部件。尽管类B 不再被使用,如果类A 对类B 的引用未被清除,类B 将继续存在并占据内存空间,即使下一次垃圾收集被执行。 什么时候需要注意内存泄漏? 如果在你的程序执行一段时间之后遇到https://www.doczj.com/doc/1c6843104.html,ng.OutOfMemoryError 的话,内存泄漏无疑是最值得怀疑的。除了这种明显的情况之外,什么时候需要考虑内存泄漏?完美主义的程序员会回答说所有的内存泄漏都需要进行审查和更改。然而,在跳到这一结论之前还需要考虑其他几点因素,包括程序的生命周期以及内存泄漏的大小。

C++Builder 内存泄漏检查工具

C++Builder 内存泄漏检查工具-CodeGuard 一、为什么写这篇东西 自己在使用BCB5写一些程序时需要检查很多东西,例如内存泄漏、资源是否有释放等等,在使用了很多工具后,发觉BCB5本身自带的工 具――CodeGuard,非常不错,使用也挺方便的,但是摸索了很久(以及翻查了一些资料,包括HELP)才算是会用了。写这篇文章的目的希望有这方面的问题的朋友可以借鉴一下,大家互相学习,共同进步。我的联系方法:Email:szbug@https://www.doczj.com/doc/1c6843104.html,,希望志同道合的朋友来信互相交流。以下这篇文章算是拼凑出来的一篇文章,一些资料是在书上找的,一些是在HELP上看到了。 二、什么是CodeGuard CodeGuard是在是C++Builder5才出现的一个工具。CodeGuard是C++Builder中一个程序在运行时期的检查器,用于检查内存或者资源的使用,以及函数调用的验证。 CodeGuard可以检测到以下的程序运行期错误: l非法的内存释放。 l无效的句柄或者文件流。 l非法指针。 l使用已被释放的指针。 l内存泄漏。 l分配但最后没有释放的内存变量。 l传递给函数的不正确的参数(包括VCL以及Win32函数)。 l函数返回值的错误。(包括VCL以及Win32函数)。 例如:在应用程序中试图多次释放相同的资源(或者已经释放了的资源)、试图访问已经被释放的内存。 三、在BCB5中怎样使用CodeGuard――配置CodeGuard 如果要使用CodeGuard的话,必须有些代码编译进你的应用程序,所以在改变以下这些设置后。必须全部重新编译(切记切记!!!)。第一、打开应用程序的工程选项的CodeGuard页框,把CodeGuard Validation前面打勾工程选项里,还有其他三个选项。第一个选项允许CodeGuard检查指向局部、全局和静态变量的无效指针和数据溢出。第二个选项允许CodeGuard检测对非法的(无效的、已删除的)对象的方法的调用。第三个选项允许CodeGuard验证内嵌指针的访问(在某些资料上说,开启这个选项会造成程序执行速度变得很慢,我测试过了,如果工程不是很大的话不是很明显,可以接受。)一般的调试是开打所有的选项(默认选择也是全部打开)。 通过CodeGuard的配置工具,可以配置CodeGuard的一些选项,在命令行方式执行CGCONFIG.EXE。可以见到一个对话框 Preferences标签页用于设置CodeGuard这个工具的全局选项。Enable选项可以在应用程序不重新编译的情况下使用或者不使用CodeGuard,一般来说是都是启用她。如果使用CodeGuard的话,建议设置工程选项来禁止或者使用CodeGuard。Stack fill frequency填充栈频率是检测对运行期栈的无效访问。 Report和Error Message Box选项是设置CodeGuard报告错误的方式。在

如何避免内存泄露

如何避免内存泄露 关于内存泄露的原因有很多,最常见的有如下几种: 1、对于通过new等运算符申请到的内存空间在使用之后没有释放掉。关于这个问题,如果 是在过程程序中开辟的空间,我们可以在过程结束时释放;但是如果是面向对象的编程,我们在类的构造函数中开辟的空间,那么我们记得一定要在析构函数中释放,但是如果析构函数出现问题了,导致不能释放内存空间,就造成了内存泄露。 2、对于程序中的windows句柄使用完要close掉。 3、对于内存的泄露有的时候是我们忘记了回收,但是有的时候是我们无法回收,比如1中 提到的析构函数不正确导致内存泄露,这是属于程序有问题;还有关于面向对象编程的一个内存泄露的可能性:一个对象在构造函数中抛出异常,对象本身的内存会被成功释放,但是其析构函数不会被调用,其内部成员变量都可以成功析构,但是用户在构造函数中动态生成的对象无法成功释放(这也在情理之中)。如果一个对象在构造函数中打开很多系统资源,但是构造函数中后续代码抛出了异常,则这些资源将不会被释放,建议在构造函数中加入try catch语句,对先前申请的资源进行释放后(也就是做析构函数该做的事情)再次抛出异常,确保内存和其他资源被成功回收。也就是说构造函数出现问题会导致构造函数中开辟的内存空间不能回收,对于对象本身的内存空间还是可以回收的。 当我们知道这些内存泄露存在的可能性时编写程序的时候就要注意,但是有的时候也会忽略这些问题,那么当发生时,我们如何来检测内存泄露呢? 可以在运行程序后,查看任务管理器,查看“内存使用和“虚拟内存大小”两项,当程序请求了它所需要的内存之后,如果虚拟内存还是持续的增长的话,就说明了这个程序有内存泄漏问题。当然如果内存泄漏的数目非常的小,用这种方法可能要过很长时间才能看的出来。 当然最简单的办法大概就是用CompuWare的BoundChecker之类的工具来检测了,不过这些工具的价格对于个人来讲稍微有点奢侈了。 一般的内存泄漏检查的确是很困难,但是也不是完全没有办法.如果你用VC的库来写东西的话,那么很幸运的是,你已经有了很多检查内存泄漏的工具,只是你想不想用的问题了. Visual C++的Debug版本的C运行库(C Runtime Library)。它已经提供好些函数来帮助你诊断你的代码和跟踪内存泄漏。而且最方便的地方是这些函数在Release版本中完全不起任何作用,这样就不会影响你的Release版本程序的运行效率。 比如下面的例子里面,有一个明细的内存泄漏。当然如果只有这么几行代码的话,是很容易看出有内存泄漏的。但是想在成千上万行代码里面检查内存泄漏问题就不是那么容易了。 char *pstr=new char[5]; lstrcpy(pstr, "Memory leak "); 我们如果我们在Debug版本的Code里面对堆(Heap)进行了操作,包括malloc,free,calloc,realloc,new和delete可以利用VC Debug运行时库中堆Debug函数来做堆的完整性和安全性检查。比如上面的代码,lstrcpy的操作明显破坏了pstr的堆结构,使其溢出,并破坏了临近的数据。那我们可以在调用lstrcpy之后的代码里面加入_CrtCheckMemory函数。_CrtCheckMemory函数发现前面的lstrcpy使得pstr的堆结构被破坏,会输出这样的报告: memory check error at 0x00372FA5=0x79, should be 0xFD. memory check error at 0x00372FA6=0x20, should be 0xFD. memory check error at 0x00372FA7=0x6C, should be 0xFD. memory check error at 0x00372FA8=0x65, should be 0xFD.

Valgrind检查内存泄露简介

内存动态分析工具Valgrind初探 用C/C++开发其中最令人头疼的一个问题就是内存管理,有时候为了查找一个内存泄漏或者一个内存访问越界,需要要花上好几天时间,如果有一款工具能够帮助我们做这件事情就好了,valgrind正好就是这样的一款工具。 Valgrind是一款基于模拟linux下的程序调试器和剖析器的软件套件,可以运行于x86, amd64和ppc32架构上。valgrind包含一个核心,它提供一个虚拟的CPU运行程序,还有一系列的工具,它们完成调试,剖析和一些类似的任务。valgrind是高度模块化的,所以开发人员或者用户可以给它添加新的工具而不会损坏己有的结构。 你可以在它的网站上下载到最新的valgrind,它是开放源码和免费的。 3.7.0版本的下载地址为https://www.doczj.com/doc/1c6843104.html,/downloads/valgrind-3.7.0.tar.bz2。 valgrind包含几个标准的工具,它们是: 1、memcheck memcheck探测程序中内存管理存在的问题。它检查所有对内存的读/写操作,并截取所有的malloc/new/free/delete调用。因此memcheck工具能够探测到以下问题:1)使用未初始化的内存 2)读/写已经被释放的内存 3)读/写内存越界 4)读/写不恰当的内存栈空间 5)内存泄漏 6)使用malloc/new/new[]和free/delete/delete[]不匹配。 2、cachegrind cachegrind是一个cache剖析器。它模拟执行CPU中的L1, D1和L2 cache,因此它能很精确的指出代码中的cache未命中。如果你需要,它可以打印出cache未命中的次数,内存引用和发生cache未命中的每一行代码,每一个函数,每一个模块和整个程序的摘要。如果你要求更细致的信息,它可以打印出每一行机器码的未命中次数。在x86和amd64上,cachegrind通过CPUID自动探测机器的cache配置,所以在多数情况下它不再需要更多的配置信息了。 3、helgrind helgrind查找多线程程序中的竞争数据。helgrind查找内存地址,那些被多于一条线程访问的内存地址,但是没有使用一致的锁就会被查出。这表示这些地址在多线程间访问的时候没有进行同步,很可能会引起很难查找的时序问题。

LeakCanary傻瓜式的内存泄露检测工具

LeakCa nary傻瓜式的内存泄露检测工具在Android 开发过程中如果需要处理图片或者大量数据的时候,常常会遇到OOM(https://www.doczj.com/doc/1c6843104.html,ng.OutOfMemoryError),—般出现最多的是在创建Bitmap上,也有可能是在内存中处理了大量的数据造成。 般会针对Bitamp 做下面几种的优化: 1. 增加进程的内存 2. 使用Bitmap.Config.ALPHA_8图片失真) 3 .显示的调用System.gc() 4. catch Exception 5. 调用bitmap.recycle() 6. 缩小bitmap 的大小(如果是读取的原图是一个大图应该先采用这种方式,Bitmap如果是刚好适配屏幕的就不需要缩小了) 7. 使用弱引用和软引用(google已经不建议使用了,Android的GC效率非常高,只要保证对象没有被引用即可) 但是我们会忽略掉一个问题就是什么造成了OOM?—般都发生OOM崩溃的 地方都不一定是内存泄露的地方,崩溃了的原因可能Activity 造成的内存泄露,也可能是操作数据库造成的内存泄露,当内存已经非常接近峰值的时候,这个时候恰巧要创建一个Bitmap对象就会发生OOM(Bitmap对象占用的内存空间比较大)。 内存泄露 每个对象都有自己的生命周期,Activity会调用onDestroy做销毁处理,但 是如果使用Activity的Con text调用Toast就会把这个Activity的引用传给了Toast而Toast的生命周期不会随着Activity的销毁而销毁,这样就造成了Activity 的内存泄露,因为它被Toast引用着。 常见的内存泄露形成的原因:

如何在linux下检测内存泄漏

如何在linux下检测内存泄漏 简介:本文针对linux下的C++程序的内存泄漏的检测方法及其实现进行探讨。其中包括C++中的new和delete的基本原理,内存检测子系统的实现原理和具体方法,以及内存泄漏检测的高级话题。作为内存检测子系统实现的一部分,提供了一个具有更好的使用特性的互斥体(Mutex)类。 1.开发背景 在windows下使用VC编程时,我们通常需要DEBUG模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名、行号以及内存大小。该功能是MFC Framework提供的内置机制,封装在其类结构体系内部。 在linux或者unix下,我们的C++程序缺乏相应的手段来检测内存信息,而只能使用top指令观察进程的动态内存总额。而且程序退出时,我们无法获知任何内存泄漏信息。为了更好的辅助在linux下程序开发,我们在我们的类库项目中设计并实现了一个内存检测子系统。下文将简述C++中的new和delete的基本原理,并讲述了内存检测子系统的实现原理、实现中的技巧,并对内存泄漏检测的高级话题进行了讨论。 2.New和delete的原理 当我们在程序中写下new和delete时,我们实际上调用的是C++语言内置的new operator和delete operator。所谓语言内置就是说我们不能更改其含义,它的功能总是一致的。以new operator为例,它总是先分配足够的内存,而后再调用相应的类型的构造函数初始化该内存。而delete operator总是先调用该类型的析构函数,而后释放内存(图1)。我们能够施加影响力的事实上就是new operator和delete operator 执行过程中分配和释放内存的方法。 new operator为分配内存所调用的函数名字是operator new,其通常的形式是void * operator new(size_t size);其返回值类型是void*,因为这个函数返回一个未经处理(raw)的指针,未初始化的内存。参数size确定分配多少内存,你能增加额外的参数重载函数operator new,但是第一个参数类型必须是size_t。 delete operator为释放内存所调用的函数名字是operator delete,其通常的形式是void operator delete(void *memoryToBeDeallocated);它释放传入的参数所指向的一片内存区。 这里有一个问题,就是当我们调用new operator分配内存时,有一个size参数表明需要分配多大的内存。但是当调用delete operator时,却没有类似的参数,那么delete operator如何能够知道需要释放该指针指向的内存块的大小呢?答案是:对于系统自有的数据类型,语言本身就能区分内存块的大小,而对于自定义数据类型(如我们自定义的类),则operator new和operator delete之间需要互相传递信息。 当我们使用operator new为一个自定义类型对象分配内存时,实际上我们得到的内存要比实际对象的内存大一些,这些内存除了要存储对象数据外,还需要记录这片内存的大小,此方法称为cookie。这一点上的实现依据不同的编译器不同。(例如MFC选择在所分配内存的头部存储对象实际数据,而后面的部分存储边界标志和内存大小信息。g++则采用在所分配内存的头4个自己存储相关信息,而后面的内存存储对象实际数据。)当我们使用delete operator进行内存释放操作时,delete operator就可以根据这些信息正确的释放指针所指向的内存块。 以上论述的是对于单个对象的内存分配/释放,当我们为数组分配/释放内存时,虽然我们仍然使用new operator和delete operator,但是其内部行为却有不同:new operator调用了operator new的数组版的兄弟-operator new[],而后针对每一个数组成员调用构造函数。而delete operator先对每一个数组成员调用析构函数,而后调用operator delete[]来释放内存。需要注意的是,当我们创建或释放由自定义数据类型所

相关主题
文本预览
相关文档 最新文档