什么是内存泄漏

原文链接:The Introduction of Memory Leaks

Java最显著的优点之一就是内存管理。你可以轻易地创建对象,然后Java垃圾回收器就会管理内存的分配与释放。然而,情况并非如此简单,因为在Java应用中,时常发生内存泄漏。

本教程将图解说明什么是内存泄漏,它为什么会发生以及如何预防它的出现。

1.什么是内存泄漏?

内存泄漏的定义:对象不再被应用程序所使用,但是垃圾回收器却不能移除它们——因为它们正在被引用。

为了理解这个定义,我们需要先理解对象在内存中的状态。下面这个图,描绘了什么是未使用以及什么是未引用。


从图中,我们可以看到被引用对象和未引用对象。未引用对象会被垃圾回收器回收,而被引用对象而不会。未引用对象一定是未使用,因为没有其他对象引用它。然而,未使用的对象并不全是未引用的。其中有些是被引用的!这就是内存泄漏的起因。

2.为什么会发生内存泄漏?

让我们一起来看下面这个例子,然后看内存泄漏为什么发生。在下面这个例子中,对象A引用了对象B。A的生命周期(t1—t4)比B的生命周期(t2—t3)要长。当B在应用程序中不再使用时,A依然持有一个它的引用。这样,垃圾回收器就不能从内存中移除B。这就可能造成内存溢出的问题,因为如果A对其他更多的对象做同样的事,那么就会有许多未被回收的对象消耗着内存空间。

同样,B也有可能持有许多其他对象的引用。这些被B引用的对象同样也不能回收。所有这些未使用的对象都将消耗着宝贵的内存空间。


3.如何预防内存泄漏?

下面是防止内存泄漏的快速实践小技巧:

1.留意Collection类,比如HashMap、ArrayList等等,因为它们一般是发现内存泄漏的地方。当它们被声明为static时,它们的生命周期就与应用程序的生命周期一样长。

2.留意事件监听器与回调。如果一个类注册了监听器,而当这个类不再使用时却没有注销监听器,那么就可能会发生内存泄漏。

3.“如果一个类,自己管理内存,那么程序员就应该警惕内存泄漏。”通常,对象中指向其他对象的成员变量应该赋值为null。

4.一个小测试:为什么在JDK6中,substring()方法会造成内存泄漏?

要回答这个问题,你可能需要阅读 SubString() in JDK 6 and 7.

你可能感兴趣的:(Java)