如何检测内存泄漏
如何查看内存泄露
主要有2种方法
借助工具,查看。
借助adb 命令来查看。
【主要原理】
借助工具来查看泄露的原因。
详细实现方式
【工具查看】
常用工具有很多例如:
1.功能强大PC端检测工具,如MemoryAnalyzer运行在PC端抓取Android手机中的dump文件进行深度分析。
2.小而优的Android端检测工具,如LeakCanary随App一起安装会在Android手机桌面安装的内存泄露检测App
详细的介绍百度里面非常多这边不做过多的介绍。
3.还有一种,要求不高的可以通过android studio查看内存变化等
【adb方式】
cmd中 敲入
adb shell dumpsys meminfo 运用包名 -d
查看的结果如下图所示:
详细看到界面,视图等占用的内存情况。
【最后】
2种方法相互使用,验证内存泄露原因。
简单说明了一下没有工具的情况如何运用VC库中的工具来检查代码的内存泄漏问题。
一: 内存泄漏
内存泄漏是编程中常常见到的一个问题,内存泄漏往往会一种奇怪的方式来表现出来,基本上每个程序都表现出不同的方式。 但是一般最后的结果只有两个,一个是程序当掉,一个是系统内存不足。 还有一种就是比较介于中间的结果程序不会当,但是系统的反映时间明显降低,需要定时的Reboot才会正常。
有 一个很简单的办法来检查一个程序是否有内存泄漏。就是是用Windows的任务管理器(Task Manager)。运行程序,然后在任务管理器里面查看 “内存使用”和”虚拟内存大小”两项,当程序请求了它所需要的内存之后,如果虚拟内存还是持续的增长的话,就说明了这个程序有内存泄漏问题。 当然如果内存泄漏的数目非常的小,用这种方法可能要过很长时间才能看的出来。
当然最简单的办法大概就是用CompuWare的BoundChecker 之类的工具来检测了,不过这些工具的价格对于个人来讲稍微有点奢侈了。
如果是已经发布的程序,检查是否有内存泄漏是又费时又费力。所以内存泄漏应该在Code的生成过程就要时刻进行检查。
二: 原因
内存泄漏产生的原因一般是三种情况:
分配完内存之后忘了回收;
程序Code有问题,造成没有办法回收;
某些API函数操作不正确,造成内存泄漏。
1. 内存忘记回收,这个是不应该的事情。但是也是在代码种很常见的问题。分配内存之后,用完之后,就一定要回收。如果不回收,那就造成了内存的泄漏,造成内存泄漏的Code如果被经常调用的话,那内存泄漏的数目就会越来越多的。从而影响整个系统的运行。比如下面的代码:
for (int =0;I<100;I++)
{
Temp = new BYTE[100];
}
就会产生 100*100Byte的内存泄漏。
2. 在某些时候,因为代码上写的有问题,会导致某些内存想回收都收不回来,比如下面的代码:
Temp1 = new BYTE[100];
Temp2 = new BYTE[100];
Temp2 = Temp1;
这样,Temp2的内存地址就丢掉了,而且永远都找不回了,这个时候Temp2的内存空间想回收都没有办法。
3. API函 数应用不当,在Windows提供API函数里面有一些特殊的API,比如FormatMessage。 如果你给它参数中有FORMAT_MESSAGE_ALLOCATE_BUFFER,它会在函数内部New一块内存Buffer出来。但是这个 buffer需要你调用LocalFree来释放。 如果你忘了,那就会产生内存泄漏。
三: 检查方法
一 般的内存泄漏检查的确是很困难,但是也不是完全没有办法。如果你用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的堆结构被破坏,会输出这样的报告:
emory 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.
DAMAGE: after Normal block (#41) at 0x00372FA0.
Normal located at 0x00372FA0 is 5 bytes long.
它 告诉说 pstr的长度应该时5个Bytes,但是在5Bytes后面的几个Bytes也被非法改写了。提醒你产生了越界操作。_CrtCheckMemory 的返回值只有TRUE和FALSE,那么你可以用_ASSERTE()来报告出错信息。 上面的语句可以换成 _ASSERTE(_CrtCheckMemory()); 这样Debug版本的程序在运行的时候就会弹出一个警告对话框,这样就不用在运行时候一直盯着Output窗口看了。这个时候按Retry,就可以进入源 代码调试了。看看问题到底出在哪里。
其他类似的函数还有 _CrtDbgReport, _CrtDoForAllClientObjects, _CrtDumpMemoryLeaks,_CrtIsValidHeapPointer, _CrtIsMemoryBlock, _CrtIsValidPointer,_CrtMemCheckpoint, _CrtMemDifference, _CrtMemDumpAllObjectsSince, _CrtMemDumpStatistics, _CrtSetAllocHook, _CrtSetBreakAlloc, _CrtSetDbgFlag,_CrtSetDumpClient, _CrtSetReportFile, _CrtSetReportHook, _CrtSetReportMode
这 些函数全部都可以用来在Debug版本中检查内存的使用情况。具体怎么使用这些函数就不在这里说明了,各位可以去查查MSDN。在这些函数中用处比较大 的,或者说使用率会比较高的函数是_CrtMemCheckpoint, 设置一个内存检查点。这个函数会取得当前内存的运行状态。 _CrtMemDifference 检查两种内存状态的异同。 _CrtMemDumpAllObjectsSince 从程序运行开始,或者从某个内存检查点开始Dump出堆中对象的信息。还有就是_CrtDumpMemoryLeaks当发生内存溢出的时候Dump出堆 中的内存信息。 _CrtDumpMemoryLeaks一般都在有怀疑是内存泄漏的代码后面调用。比如下面的例子:
#include
#include
void main()
{
char * pstr;
pstr = new char[5];
_CrtDumpMemoryLeaks();
}
输出:
Detected memory leaks! à提醒你,代码有内存泄漏.
Dumping objects ->
{44} normal block at 0x00372DB8, 5 bytes long.
Data: CD CD CD CD CD
Object dump complete.
如 果你双击包含行文件名的输出行,指针将会跳到源文件中内存被分配地方的行。当无法确定那些代码产生了内存泄漏的时候,我们就需要进行内存状态比较。在可疑 的代码段的前后设置内存检查点,比较内存使用是否有可疑的变化。以确定内存是否有泄漏。为此要先定义三个_CrtMemState 对象来保存要比较的内存状态。两个是用来比较,一个用了保存前面两个之间的区别。
_CrtMemState Sh1,Sh2,Sh_Diff;
char *pstr1 = new char[100];
_CrtMemCheckPoint(&Sh1); ->设置第一个内存检查点
char *pstr2 = new char[100];
_CrtMemCheckPoint(&Sh2); ->设置第二个内存检查点
_CrtMemDifference(&Sh_Diff, &Sh1, &Sh2); ->检查变化
_CrtMemDumpAllObjectsSince(&Sh_Diff); ->Dump变化
如 果你的程序中使用了MFC类库,那么内存泄漏的检查方法就相当的简单了。因为Debug版本的MFC本身就提供一部分的内存泄漏检查。 大部分的new 和delete没有配对使用而产生的内存泄漏,MFC都会产生报告。这个主要是因为MFC重载了Debug版本的new 和delete操作符, 并且对前面提到的API函数重新进行了包装。在MFC类库中检查内存泄漏的Class就叫 CMemoryState,它重新包装了了_CrtMemState,_CrtMemCheckPoint, _CrtMemDifference, _CrtMemDumpAllObjectsSince这些函数。并对于其他的函数提供了Afx开头的函数,供MFC程序使用。比如 AfxCheckMemory, AfxDumpMemoryLeaks 这些函数的基本用法同上面提到的差不多。 CMemoryState和相关的函数的定义都在Afx.h这个头文件中。 有个简单的办法可以跟踪到这些函数的声明。在VC中找到MFC程序代码中下面的代码, 一般都在X.cpp的开头部分
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
把 光标移到DEBUG_NEW上面 按F12,就可以进入Afx.h中定义这些Class和函数的代码部分。 VC中内存泄漏的常规检查办法主要是上面的两种。当然这两种方法只是针对于Debug版本的Heap的检查。如果Release版本中还有内存泄漏,那么 检查起来就麻烦很多了。
4 .总结:
实际上Heap的内存泄漏问题是相当的好查的。VC的提供的检查工具也不太少,但是如果是栈出了什么问题,恐怕就麻烦很多了。栈出问题,一般不会产生内存泄漏,但是你的代码的逻辑上很有可能会有影响。这个是最最痛苦的事情。 编程,就是小心,小心再小心而已。
可以使用相应的软件测试工具对软件进行检测。
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. MEMWATCH-由Johan
Lindh编写,是一个开放源代码C语言内存错误检测工具,主要是通过gcc的precessor来进行。
7. Valgrind-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-是一款开源的JAVA内存分析软件,可用于辅助查找JAVA程序的内存泄漏,能容易找到大块内存并验证谁在一直占用它,它是基于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
Visual C++的一个插件运行。
16. Compuware DevPartner for Visual C++ BoundsChecker
Suite-为C++开发者设计的运行错误检测和调试工具软件。作为Microsoft Visual Studio和C++ 6.0的一个插件运行。
17. Electric Software GlowCode-包括内存泄漏检查,code
profiler,函数调用跟踪等功能。给C++和.Net开发者提供完整的错误诊断,和运行时性能分析工具包。
18. Compuware DevPartner Java
Edition-包含Java内存检测,代码覆盖率测试,代码性能测试,线程死锁,分布式应用等几大功能模块。
19. Quest JProbe-分析Java的内存泄漏。
20. ej-technologies JProfiler-一个全功能的Java剖析工具,专用于分析J2SE和J2EE应用程序。它把CPU、执行绪和内存的剖析组合在一个强大的应用中。JProfiler可提供许多IDE整合和应用服务器整合用途。JProfiler直觉式的GUI让你可以找到效能瓶颈、抓出内存泄漏、并解决执行绪的问题。4.3.2注册码:A-G666#76114F-1olm9mv1i5uuly#0126
21. BEA JRockit-用来诊断Java内存泄漏并指出根本原因,专门针对Intel平台并得到优化,能在Intel硬件上获得最高的性能。
22. SciTech Software AB .NET Memory
Profiler-找到内存泄漏并优化内存使用针对C#,VB.Net,或其它.Net程序。
23. YourKit .NET & Java Profiler-业界领先的Java和.NET程序性能分析工具。
24. AutomatedQA AQTime-AutomatedQA的获奖产品performance profiling和memory
debugging工具集的下一代替换产品,支持Microsoft, Borland, Intel, Compaq 和
GNU编译器。可以为.NET和Windows程序生成全面细致的报告,从而帮助您轻松隔离并排除代码中含有的性能问题和内存/资源泄露问题。支持.Net
1.0,1.1,2.0,3.0和Windows 32/64位应用程序。
25. JavaScript Memory Leak Detector-微软全球产品开发欧洲团队(Global Product
Development- Europe team, GPDE)
发布的一款调试工具,用来探测JavaScript代码中的内存泄漏,运行为IE系列的一个插件。
1 内存泄露就是指在程序中出现动态分配的内存单元,使用结束后没有释放的情况。
2 调试运行时,内存泄露一般屏幕上会现现memory leak字样的英文。
检测内存泄露
尽管优秀的编程实践可以确保最少的泄漏,但是根据经验,当使用大量的函数对相同的内存块进行处理时,很可能会出现内存泄漏。尤其是在碰到错误路径的情况下更是如此。检测是否有内存泄露的一个小技巧:就是打开windows任务管理器选到性能的菜单项,,然后运行你的程序,看windows任务管理器选到性能的菜单项中...
排查内存泄漏最简单和直观的方法
先说一个terminal指令: 这条指令是用来查询这个进程所占用的内存的具体详情的,通过这条指令可以看到当前app在手机中占用的具体的堆内存大小,view的数量, activity的数量 ,等等。如下图:其中activity数目是非常关键的一个信息,可以帮助我们快速地检测出内存泄漏。我们可以反复地进入退出需要测试的...
干货!Windbg 在 TDengine 内存泄漏调试中的应用与实践分享
通常,内存泄漏的检测涉及监控程序运行时的内存申请和释放情况。Windbg通过gflags组件记录这些信息,通过umdh组件进行两次内存快照,比较快照差异,找出未释放的内存申请,调用栈信息通常能帮助定位泄漏点。实践中,如taosdump在Windows导入数据时遇到的内存溢出问题,通过配置gflags,设置跟踪目标,生成快照并对比...
内存泄漏表现
内存泄漏通常在服务进程中更易引发问题,因为这类进程通常以无限循环的方式运行。内核内存泄漏尤其危险,因为内核问题可能影响整个系统的稳定性。目前,定位和追踪内核内存泄漏的工具相对匮乏,尽管用户空间有一些静态和动态分析工具,但对内核内存泄漏的检测并不易行。内存泄漏与对象的引用计数密切相关,特别是在...
Windows 下有哪些内存泄露监测工具
在Windows平台下,检测内存泄漏的工具常用的一般有三种,MS C-Runtime Library内建的检测功能;外挂式的检测工具,诸如,Purify,BoundsChecker等;利用Windows NT自带的Performance Monitor。这三种工具各有优缺点,MS C-Runtime Library虽然功能上较之外挂式的工具要弱,但是它是免费的;Performance Monitor...
如何在Android Studio中使用LeakCanary检测内存泄露
内存泄露检测是项目性能优化不可避免的问题,只有解决内存泄露问题才能从根本上解决OOM。在Eclipse中提供Mat工具来检测内存泄露,但是使用较为麻烦,界面也不是很直观。对于有耐心,有想法的,也是可以尝试了解一下。知道Leak的出现,为内存泄露检测带来了福音。1.什么是LeakCanary LeakCanaryA memory leak ...
android性能优化之leakcanary如何使用?
概述: 使用LeakCanary简化内存泄漏检测 LeakCanary由Square公司开发,旨在简化内存泄漏分析。相较于MAT分析,它提供了一种更简便、快速的方式。配置与使用: 在应用的build.gradle中进行配置,并在Application类中加入特定代码,以实现LeakCanary的安装与使用。当检测到内存泄漏时,LeakCanary会提供相应的提示。应用...
Android开发中,有什么工具能够排查jni层的内存泄漏
这个值就是你的应用真正占据的内存大小,通过这个信息,你可以轻松判别手机中哪些程序占内存比较大了。4. 总结 关于Android开发中内存的使用情况和内存泄漏的检测就简单介绍到这里,基本上用以上三种方式都能够定位内存泄漏问题,平时在使用Bitmap,数据库和JNI层C\/C++编程的时候,注意一点就行。另外,如果...
如何使用工具进行C\/C++的内存泄漏检测
该工具可以检测下列与内存相关的问题 :未释放内存的使用对释放后内存的读\/写对已分配内存块尾部的读\/写内存泄露不匹配的使用malloc\/new\/new[] 和 free\/delete\/delete[]重复释放内存注意: 上面列出的并不很全面,但却包含了能被该工具检测到的很多普遍的问题.让我们一个一个地对上面的场景进行讨论:注意: 下面...
如何检查C++中的内存泄漏
int* p=new int;p=new int; \/\/p指针修改,原来申请内存的地址没有记录下来,于是无法释放 下面介绍如何检查内存泄漏:1.包含头文件和定义 define _CRTDBG_MAP_ALLOC \/\/并非绝对需要该语句,但如果有该语句,打印出来的是文件名和行数等更加直观的信息 include <stdlib.h> include <crtdbg....
徭榕妇科: 内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费.可以使用相应的软件测试工具...
宝应县18824295808: 如何检测内存泄漏?
徭榕妇科: http://www.devdiv.com/forum.php?mod=viewthread&tid=87206&highlight=%C4%DA%B4%E6%D0%B9%C2%A9看看这个有没有帮助还有就是可以通过DDMS查看内存消耗情况
宝应县18824295808: 测试内存泄漏的方法与技巧 - ?
徭榕妇科: 测试人员,也分白盒测试和黑盒测试,在白盒测试阶段不去关注,反而想通过黑盒测试得到内存泄露情况,不是很麻烦吗?那要看程序的特点了! 如果对于源代码和运行流程没有了解,估计很难有针对性的判断. 如果有所了解,可以有目的的输入入一些数据,控制程序的流动方向,也许可以更有效一点儿!不是源代码察看工具的话,就要长时间运行一个程序,察看内存占用是否是一直增加了!
宝应县18824295808: 如何查找内存泄露 - ?
徭榕妇科: 这两天,在查找内存泄露的问题.因为内存都是放在memory pool里,所以不能通过valgrind等工具抓到那个地方分配的内存没有手动被释放.使用gcc,有一个方法去打包内存分配函数,而且不需要编辑已有的code并且不需要修改目标文件....
宝应县18824295808: 怎样发现内存泄露? - ?
徭榕妇科: 这里的客户端软件包括C/S系统的客户端和B/S系统中的客户端控件,当用户使用客户端软件时,如果发现我们的软件会吃内存,那是很丢面子的事,有哪些好的测试方法呢?希望大家能踊跃提出自己的看法. 如何发现客户端软件中的内存泄露...
宝应县18824295808: 如何在linux下检测内存泄漏 - ?
徭榕妇科: 检测内存泄露主要有以下5种方法:1、在需要内存泄漏检查的代码的开始调用void mtrace(void) (该函数在头文件mcheck.h中有声明).mtrace为malloc等函数安装hook,用于记录内存分配信息.在需要内存泄漏检查的代码的结束调用void ...
宝应县18824295808: 如何用最简单的方法判断内存泄漏!?
徭榕妇科: shift+alt+del,看任务管理器,性能选项里面有个PF使用率就是
宝应县18824295808: 系统测试中怎么确定内存泄露 - ?
徭榕妇科: 是不是说没有一种内存检查工具能够在linux使用呢,也不是,像valgrind工具还是相当不错的.他的下载地址是下载一个valgrind3.2.3(tar.bz2)工具,按照里面的README提示,安装后就可以使用这个工具来检测内存泄露和内存越界等.这是一个...
宝应县18824295808: 内存泄露有哪些方法定位,崩溃有哪些方法定位 - ?
徭榕妇科: ios怎么查看内存泄露,有以下几种方法供大家参考: 1. 静态分析 2. 通过静态分析我们可以最初步的了解到代码的一些不规范的地方或者是存在的内存泄漏,这是我们第一步对内存泄漏的检测.当然有一些警告并不是我们关心的可以略过. 3. ...
宝应县18824295808: 一个方便的检测内存泄露的方法?
徭榕妇科: MFC中的CMemoryState 类. 这个类非常有用,它可以给当前内存照个快照,并可以将内存快照进行比对.如果你想确认程序在某个时段中分配的内存全部被正确的释放,那可以在这个时段开始时照个快照,结束后再照一个.如果这个两个快...