内存泄漏

(memory leak),指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。



在编程时进行动态内存分配是非常必要的,它可以在程序运行的过程中帮助分配所需的内存,而不是在进程启动的时候就进行分配。



然而有效地管理这些内存同样也是非常重要的。



在大型的、复杂的应用程序中,内存泄漏是常见的问题,当以前分配的一片内存不再需要使用或无法访问时,但是却并没有释放它,那么对于该进程来说,会因此导致总可用内存的减少,这时就出现了内存泄漏。











常见

检测

内存泄漏的工具:











C/C++


1.




Valgrind





Debugging and profiling Linux programs, aiming at programs written in C and C++.



2.




ccmalloc





Linux



Solaris

下对

C



C++

程序的简单的使用内存泄漏和

malloc

调试库。

3.




LeakTracer





Linux



Solaris



HP-UX

下跟踪和分析

C++

程序中的内存泄漏。

4.




Electric Fence





Linux

分发版中由

Bruce Perens

编写的

malloc()

调试库。

5.




Leaky





Linux

下检测内存泄漏的程序。

6.




Dmalloc





Debug Malloc Library.

7.




MEMWATCH



-由

Johan Lindh

编写,是一个开放源代码

C

语言内存错误检测工具,主要是通过

gcc



precessor

来进行。

8.




KCachegrind





A visualization tool for the profiling data generated by


Cachegrind


and


Calltree


.


Java

1.


Memory Analyzer



-是一款开源的

JAVA

内存分析软件,查找


内存泄漏,能容易找到大块内存并验证谁在一直占用它,它是基于

Eclipse RCP(Rich Client Platform)

,可以下载

RCP

的独立版本或者

Eclipse

的插件。

2.


JProbe



-分析

Java

的内存泄漏。

3.


JProfiler



-一个全功能的

Java

剖析工具,专用于分析

J2SE



J2EE

应用程序。它把

CPU

、执行绪和内存的剖析组合在一个强大的应用中,



GUI

可以找到效能瓶颈、抓出内存泄漏、并解决执行绪的问题。

4.


JRockit



-用来诊断

Java

内存泄漏并指出根本原因,专门针对

Intel

平台并得到优化,能在

Intel

硬件上获得最高的性能。

5.


YourKit


.NET & Java Profiling

业界领先的

Java



.NET

程序性能分析工具。


6.


AutomatedQA





AutomatedQA

的获奖产品

performance profiling



memory debugging

工具集的下一代替换产品,支持

Microsoft, Borland, Intel, Compaq



GNU

编译器。可以为

.NET



Windows

程序生成全面细致的报告,从而帮助您轻松隔离并排除代码中含有的性能问题和内存

/

资源泄露问题。支持

.Net 1.0,1.1,2.0,3.0



Windows 32/64

位应用程序。



7. Compuware


DevPartner Java Edition



-包含

Java

内存检测

,

代码覆盖率测试

,

代码性能测试

,

线程死锁

,

分布式应用等几大功能模块。


.NET

1.


.NET Memory Profiler






找到内存泄漏并优化内存使用针对

C#



VB.Net

,或其它

.Net

程序。

2.


Windows Leaks Detector



-探测任何

Win32

应用程序中的任何资源泄漏

(

内存,句柄等

)

,基于

Win API

调用钩子。

3.


DTrace





一款开源

动态跟踪

Dynamic Tracing,

能在

Unix

类似平台运行,用户能够动态检测操作系统内核和用户进程,以更精确地掌握系统的资源使用状况,提高系统性能,减少支持成本,并进行有效的调节。

4. IBM Rational


PurifyPlus



-帮助开发人员查明

C/C++

、托管

.NET



Java



VB6

代码中的性能和可靠性错误。

PurifyPlus

将内存错误和泄漏检测、应用程序性能描述、代码覆盖分析等功能组合在一个单一、完整的工具包中。

5. Parasoft


Insure++



-针对

C/C++

应用的运行时错误自动检测工具,它能够自动监测

C/C++

程序,发现其中存在着的内存破坏、内存泄漏、指针错误和

I/O

等错误。并通过使用一系列独特的技术(

SCI

技术和变异测试等),彻底的检查和测试我们的代码,精确定位错误的准确位置并给出详细的诊断信息。能作为

Microsoft Visual C++

的一个插件运行。

6. Compuware


DevPartner for Visual C++ BoundsChecker Suite



-为

C++

开发者设计的运行错误检测和调试工具软件。作为

Microsoft Visual Studio



C++ 6.0

的一个插件运行。

7. Electric Software


GlowCode



-包括内存泄漏检查,

code profiler

,函数调用跟踪等功能。给

C++



.Net

开发者提供完整的错误诊断,和运行时性能分析工具包。


FireFox / IE

1.




Leak Monitor



-一个

Firefox

扩展,能找出跟

Firefox

相关的泄漏类型。

2.


IE Leak Detector (Drip/IE Sieve)





Drip



IE Sieve leak detectors

帮助网页开发员提升动态网页性能通过报告可避免的因为

IE

局限的内存泄漏。


3.




JavaScript Memory Leak Detector




-微软全球产品开发欧洲团队


(Global Product Development- Europe team, GPDE)


发布的一款调试工具,用来探测


JavaScript


代码中的内存泄漏,运行为


IE


系列的一个插件。





内存泄漏的发生方式


1.




常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。


2.




偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。


3.




一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏。


4.




隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。



什么是系统资源


当应用程序在


Windows


中运行时,


Windows


必须实时


"


跟踪


"


该应用程序的运行,并保留与之相关的许多信息,如按钮、光标、菜单的位置和位图、窗口的状况等,这些信息由


Windows


保留在一种叫堆的内存块中,堆的英文为


Heap


。简单地说,堆是采用特殊机制管理的内存块。由


Windows


的一个系统内核


User.exe


管理的堆叫做


User


资源堆(


User Resource Heap


),由另一个系统内核


Gdi.exe


管理的堆叫做


GDI


资源堆(


Graphical Device Interface Resource Heap


,简称


GDI Resource Heap


),


User


资源堆和


GDI


资源堆合称为系统资源堆(


System Resource Heap


),习惯上就把它们叫做系统资源(


System Resource


)。




微软将


Windows


的系统资源(堆)分为五个堆,其中


User


资源堆为三个,而


GDI


资源堆为两个。



三个


User


资源堆分别是:


16


位的用户堆(


User Heap





64KB


);


32


位的窗口堆(


Windows Heap





2MB


);


32


位的用户菜单堆(


User Menu Heap





2MB


)。





两个


GDI


资源堆分别是:



16


位的


GDI


堆(


GDI Heap





64KB


);


32


位的


GDI


堆(


GDI





2MB


)。


从这里的系统资源分类和大小我们应该明白,不管


CPU





P4


还是


486


,内存是


8M


还是


1G


,所有


Windows


的用户都拥有同样大小的系统资源(堆),用户不能自已增加或减少系统资源的大小,这是由操作系统决定的,与硬件档次没有任何关系。


Windows





User


资源堆和


GDI


资源堆的可用(


Free


)空间称为可用


User


资源和可用


GDI


资源,


Windows


中以百分数表示它们,用户可以选择


"


开始


/


附件


/


系统工具


/


系统信息


"


,来实时查看它们的大小。





Java内存泄露的理解与解决




Java内存溢出(OutOfMemory)工具