Java記憶體泄露
記得上次去XX公司面試,一個面試官問我Java有沒有記憶體泄露,我說有,但接下來我一下子愣了,面試官立刻很肯定地給我糾正,Java是沒有記憶體泄露的情況,我不敢再辯了,我知道當時的情況,這也是毫無疑義的。回來之後我再查了下資料,整理了一下,記憶體泄露的幾種情況,免得走向誤區,現在給大家分享下吧
Java和C++中一個很大的區別就是Java有記憶體回收機制GC自動管理記憶體的回收,因此開發人員不需要調用方法來釋放記憶體,而C++沒有自動回收記憶體的機制,所以處處都需要留意記憶體的回收情況,萬一不注意就可能出現記憶體泄露的情況。
但這是不是就表明Java就沒有記憶體泄露的問題呢。答案是否定的,也有些情況也會導致Java編寫的程式出現記憶體泄露的問題。
Java記憶體回收機制
不論哪種語言的記憶體配置方式,都需要返回所分配記憶體的其真實位址,也就是返回一個指標到記憶體塊的首地址。Java中對象是採用new或者反射的方法建立的,這些對象的建立都是在堆(Heap)中分配的,所有對象的回收都是由Java虛擬機器通過記憶體回收機制完成的。GC為了能夠正確釋放對象,會監控每個對象的健全狀態,對他們的申請、引用、被引用、賦值等狀況進行監控,Java會使用有向圖的方法進行管理記憶體,即時監控對象是否可以達到,如果不可到達,則就將其回收,這樣也可以消除引用迴圈的問題。在Java語言中,判斷一個記憶體空間是否符合垃圾收集標準有兩個:一個是給對象賦予了空值null,以下再沒有調用過,另一個是給對象賦予了新值,這樣重新分配了記憶體空間。
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對象被回收了,實際上v引用了這些對象,還被引用的對象GC是沒有辦法回收的,這樣就很可能導致記憶體的泄露。
哪裡分析錯或者需要補充的地方,希望得到指點,謝謝