Java內存泄露簡述


Java的一個最顯著的優勢是內存管理。你只需要簡單的創建對象而不需要負責釋放空間,因為Java的垃圾回收器會負責內存的回收。然而,情況並不是這樣簡單,內存泄露還是經常會在Java應用程序中出現。

本篇文章將介紹什么是內存泄露,為什么會發生,以及怎樣阻止內存泄露。

什么是內存泄露

內存泄露的定義:對於應用程序來說,當對象已經不再被使用,但是Java的垃圾回收器不能回收它們的時候,就產生了內存泄露。

要理解這個定義,我們需要理解對象在內存中的狀態。如下圖所示,展示了哪些對象是無用對象,哪些是未被引用的對象;

上圖中包含了未引用對象和引用對象。未引用對象將會被垃圾回收器回收,而引用對象卻不會。未引用對象很顯然是無用的對象。然而,無用的對象並不都是未引用對象,有一些無用對象也有可能是引用對象,這部分對象正是內存泄露的來源。

為什么內存泄露會發生

讓我們用下面的例子來看看為什么會發生內存泄露。如下圖所示,對象A引用對象B,A的生命周期(t1-t4)比B的生命周期(t2-t3)要長,當B在程序中不再被使用的時候,A仍然引用着B。在這種情況下,垃圾回收器是不會回收B對象的,這就可能造成了內存不足問題,因為A可能不止引用着B對象,還可能引用其它生命周期比A短的對象,這就造成了大量無用對象不能被回收,且占據了昂貴的內存資源。

同樣的,B對象也可能引用着一大堆對象,這些被B對象引用着的對象也不能被垃圾回收器回收,所有的這些無用對象消耗了大量內存資源。

怎樣阻止內存泄露

以下是一些阻止內存泄露的經驗提示:

  1. 多關注集合類,比如HashMap,ArrayList等,這些對象經常會發生內存泄露。比如當它們被聲明為靜態對象時,它們的生命周期會跟應用程序的生命周期一樣長,很容易造成內存不足。
  2. 多關注事件監聽(listeners)和回調(callbacks),比如注冊了一個listener,當它不再被使用的時候,忘了注銷該listener,可能就會產生內存泄露。
  3. “如果一個類自己管理自己的內存空間,開發人員需要特別警惕內存泄露”,引用其它對象的成員變量記得要置為null?不太理解(原文:Often times member variables of an object that point to other objects need to be null out)

小測驗:為什么jdk 6的substring()方法會導致內存泄露

詳情請看以下鏈接:
http://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/

 

譯文鏈接:http://www.programcreek.com/2013/10/the-introduction-of-memory-leak-what-why-and-how/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM