翻译自这篇文章
Java一个最显著的优势就是它的内存管理。你只需要简单地创建对象,而Java垃圾收集器会负责内存的分配与释放。不过,事情并没有那么简单,因为在Java应用中时常会出现内存泄漏。
1. 什么是内存泄漏?
内存泄漏的定义: 对象不再被程序使用,但是因为它们仍在被引用导致垃圾收集器无法删除它们。
要理解这个定义,我们首先需要理解对象在内存中的状态。下图说明了什么是无使用的,以及什么是无引用的。
由上图可知,内存中有引用对象和无引用对象。无引用对象会被垃圾收集处理掉,而引用对象不会被当做垃圾处理。无引用对象一点是无使用的,因为没有其它对象与它关联。但是,无使用对象不一定是无引用的。其中有一些是被引用的!这就是内存泄漏的由来。
2. 为什么会发生内存泄漏?
我们来根据下面的例子看看为什么会发生内存泄漏。在下面的例子中,对象A引用了对象B。A的生命周期(t1 - t4)要比B的生命周期(t2 - t3)长很多。当B不再被程序使用时,A仍然保持对B的引用。这种情况下,垃圾收集器就无法从内存中删除B。这可能会造成内存不足的问题,因为如果A对更多的对象都是同样的引用,那么就会有很多无法收集的对象消耗内存空间。
也有可能B对一些其它的对象保留着引用。那些被B引用的对象也将无法被回收。所有这些未被使用的对象都将消耗宝贵的内存空间。
3. 如何避免内存泄漏?
下面是一些避免内存泄漏的实用技巧。
- 注意集合类,如HashMAP,ArrayList,等等,因为这些地方经常出现内存泄漏。当它们被声明为
static
时,它们的生命周期就与应用本身一样长。 - 注意时间监听器与回调函数。对于一个已注册的监听器,如果对应类不再被使用的时候,它没有被注销,那么也可能会发生内存泄漏。
- “如果一个类可以管理它自己的内存,那么程序员就应该警惕内存泄漏的问题”。通常,一个类中指向其它类的成员变量需要被清空。