Java的一個最顯著的優勢是內存管理。你只需要簡單的創建對象而不需要負責釋放空間,因為Java的垃圾回收器會負責內存的回收。然而,情況並不是這樣簡單,內存洩露還是經常會在Java應用程序中出現。
本篇文章將介紹什麼是內存洩露,為什麼會發生,以及怎樣阻止內存洩露。
內存洩露的定義:對於應用程序來說,當對象已經不再被使用,但是Java的垃圾回收器不能回收它們的時候,就產生了內存洩露。
要理解這個定義,我們需要理解對象在內存中的狀態。如下圖所示,展示了哪些對象是無用對象,哪些是未被引用的對象;
上圖中包含了未引用對象和引用對象。未引用對象將會被垃圾回收器回收,而引用對象卻不會。未引用對象很顯然是無用的對象。然而,無用的對象並不都是未引用對象,有一些無用對象也有可能是引用對象,這部分對象正是內存洩露的來源。
讓我們用下面的例子來看看為什麼會發生內存洩露。如下圖所示,對象A引用對象B,A的生命周期(t1-t4)比B的生命周期(t2-t3)要長,當B在程序中不再被使用的時候,A仍然引用著B。在這種情況下,垃圾回收器是不會回收B對象的,這就可能造成了內存不足問題,因為A可能不止引用著B對象,還可能引用其它生命周期比A短的對象,這就造成了大量無用對象不能被回收,且占據了昂貴的內存資源。
同樣的,B對象也可能引用著一大堆對象,這些被B對象引用著的對象也不能被垃圾回收器回收,所有的這些無用對象消耗了大量內存資源。
以下是一些阻止內存洩露的經驗提示: