[译]Java内存泄露介绍

时间:2023-03-09 22:50:13
[译]Java内存泄露介绍

(本文章翻译自the-introduction-of-memory-leak-what-why-and-how

Java最大的优势之一就是它的内存管理机制。你可以简单创建对象然后垃圾回收器会负责分配内存和回收释放内存。但是,实际上情况不是这么简单的。因为在Java应用程序中内存泄露是很频繁的发生。

这篇文章将解释什么是内存泄露,为什么会发生还有就是这么去避免内存泄露。

1.什么是内存泄露

内存泄露定义:对象不再被应用程序使用了但是垃圾回收器不会回收他们因为他们还被引用着。

为了理解这个定义,我们需要了解对象在内存中的状态。下面的图将会表名什么是不再使用什么是不再被引用了。
[译]Java内存泄露介绍

上面的图中有被引用的对象还有不再被引用的对象。不被引用的对象将会被垃圾回收器回收,但是对于被引用的对象将不会被回收。不被引用的对象肯定没有再被使用了,因为没有其他对象指向它了。但是,不再使用的对象并不全是不被引用着。他们中的一些对象仍然被引用着,这就是为什么会发生内存泄露的原因。

2.为什么内存泄露会发生

让我们看一下下面的例子看看为什么内存泄露会发生。在下面的例子中,对象A指向对象B,A的生命周期(t1-t4)比B(t2-t3)的长些,当B不再被程序使用的时候,A仍然拥有一个指向它的引用。在这种情况下,垃圾回收器不会将B从内存中回收。这可能会导致内存问题,因为A对其他对象做同样的事情,那么他们也不能被回收而且消耗内存。

也有可能B拥有一些其他对象的引用。这些对象被B引用的对象也不能回回收的。所有这些不被使用的对象仍然会消耗以前的内存空间。

[译]Java内存泄露介绍

3.怎么样才能避免内存泄露

下面是一些不错的建议可以避免内存泄露问题

1.留心那些集合类,比如HashMap,ArrayList等等,因为他们经常发生内存泄露情况。当他们被申明为static类型是,他们的生命周期就和程序的生命周期一样了。

2.留心那些监听事件和回调事件。如果监听器被注册但不是未注册的侦听器类时不再被使用时内存泄漏可能发生。

3.如果一个类自己管理自己的内存那么程序员应该在发生内存泄露的是偶给出告警。要时刻记住指向其他对象的对象变量在不用的时候应该设置为null

4.一个小测试:为什么JDK6中的substring()方法会引起内存泄露

为了回答这个问题,你可以阅读Substring() in JDK 6 and 7.