標籤:
記憶體管理一直是Java 所鼓吹的強大優點。開發人員只需要簡單地建立對象,而Java的垃圾收集器將會自動管理記憶體空間的分配和釋放.但在很多情況下,事情並不那麼簡單,在 Java程式中總是會頻繁地發生記憶體泄露(Memory Leaks).
記憶體泄露是什麼?
記憶體泄露的定義: 當某些對象不再被應用程式所使用,但是由於仍然被引用而導致垃圾收集器不能釋放(Remove,移除)他們.
用白話來說就是: 該回收的記憶體沒被回收,最後因為記憶體不夠用而導致程式報錯。
要理解這個定義,我們需要理解記憶體中的對象狀態. 展示了什麼是不使用的部分,以及未被引用的部分。
圖1
可以看出,記憶體中存在著 有引用的對象,和無引用的對象. 無引用的對象將被垃圾收集器所回收,而有引用的對象則不會被當做垃圾收集. 因為沒有任何其他對象所引用,所以無引用對象一定是不再使用的。 但是有一部分無用對象仍然被(無意中)引用著。這就是發生記憶體泄露的根源.
為什麼記憶體會泄露?
讓我們看下面的執行個體來瞭解為什麼記憶體會泄露. 在下面的情境中,對象A引用了對象B. A的生命週期(t1 - t4) 比 B的(t2 - t3)要長得多. 當對象B在應用程式邏輯中不會再被使用以後, 對象 A 仍然持有著 B的引用. (根據虛擬機器規範)在這種情況下垃圾收集器不能將 B 從記憶體中釋放. 這種情況很可能會引起記憶體問題,假若A 還持有著其他對象的引用,那麼這些被引用的(無用)對象都不會被回收,並佔用著記憶體空間.
甚至有可能 B 也持有一大堆其他對象的引用。 這些對象由於被 B 所引用,也不會被垃圾收集器所回收. 所有這些無用的對象將消耗大量寶貴的記憶體空間。
圖2
怎麼防止記憶體泄露?
要防止記憶體泄露,下面是一些快速上手的實用技巧:
1. 當心集合類,比如 HashMap,ArrayList等,因為這是最容易發生記憶體泄露的地方.當集合對象被聲明為static時,他們的生命週期一般和整個應用程式一樣長。
2. 注意事件監聽和回調.當註冊的監聽器不再使用以後,如果沒有被登出,那麼很可能會發生記憶體泄露.
3. "當一個類自己管理其記憶體空間時,程式員應該注意記憶體泄露." 常常是一個對象的成員變數需要被置為null 時仍然指向其他對象,
參考:http://blog.csdn.net/renfufei/article/details/14138099
http://blog.csdn.net/renfufei/article/details/14669513
java 記憶體泄露(一)