java內存泄露

說到內存泄露,很多人都不是特別明白是什麼概念,還有很多人把它和oom混淆了,oom是out of memory 內存溢出,和內存泄露並不是同一個概念。內存泄露可能導致內存溢出。內存泄露的定義是:內存泄漏也稱作“存儲滲漏”,用動態存儲分配函數動態開闢的空間,在使用完畢後未釋放,結果導致一直佔據該內存單元。直到程序結束。(其實說白了就是該內存空間使用完畢之後未回收)即所謂內存泄漏。

C++中的內存需要程序員手動釋放與分配,而Java中有着內存回收機制,是不是就意味着沒有內存泄露的問題呢,答案是否定。想要了解Java內存泄露首先要了解一下java的內存回收機制:

Java中對內存對象的訪問,使用的是引用的方式。在 Java 代碼中我們維護一個內存對象的引用變量,通過這個引用變量的值,我們可以訪問到對應的內存地址中的內存對象空間。在 Java 程序中,這個引用變量本身既可以存放堆內存中,又可以放在代碼棧的內存中(與基本數據類型相同)。 GC 線程會從代碼棧中的引用變量開始跟蹤,從而判定哪些內存是正在使用的。如果 GC 線程通過這種方式,無法跟蹤到某一塊堆內存,那麼 GC 就認爲這塊內存將不再使用了(因爲代碼中已經無法訪問這塊內存了)。
通過這種有向圖的內存管理方式,當一個內存對象失去了所有的引用之後,GC 就可以將其回收。反過來說,如果這個對象還存在引用,那麼它將不會被 GC 回收,哪怕是 Java 虛擬機拋出 OutOfMemoryError 。

java內存泄露常見的原因:

1、靜態集合類像HashMap、Vector等的使用最容易出現內存泄露,這些靜態變量的生命週期和應用程序一致,所有的對象Object也不能被釋放,因爲他們也將一直被Vector等應用着。

2、內部類和外部類的引用容易出現內存泄露的問題

3、監聽器的使用,java中往往會使用到監聽器,在釋放對象的同時沒有相應刪除監聽器的時候也可能導致內存泄露。

4、大量臨時變量的使用,沒有及時將對象設置爲null也可能導致內存的泄露

5、數據庫的連接沒有關閉情況,包括連接池方法連接數據庫,如果沒有關閉ResultSet等也都可能出現內存泄露的問題。

所以如果一個對象的生命週期超過了程序對 它的需要那麼就可以認爲發生了內存泄露。下面舉一個很經典的例子:

Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
	Object o=new Object();
	v.add(o);
	o=null;	
}
上面的例子中我們把o設置成null希望他可以被GC回收,但是由於Vector持有了他的引用所以,o是無法被回收的,我們想要釋放o的內存除了要把v設置成null還需要在vector中手動的remove掉他。

這是我自己關於java內存泄露的一些看法,如果有不對的地方歡迎大家指正,另外過兩天我會在寫一個關於安卓中內存泄露博客。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章