1. 程式人生 > >Java記憶體洩露的一個小例子

Java記憶體洩露的一個小例子

Java記憶體洩露

    一般來說記憶體洩漏有兩種情況。一種情況如在C/C++語言中的,在堆中的分配的記憶體,在沒有將其釋放掉的時候,就將所有能訪問這塊記憶體的方式都刪掉(如指標重新賦值);另一種情況則是在記憶體物件明明已經不需要的時候,還仍然保留著這塊記憶體和它的訪問方式(引用)。第一種情況,在Java中已經由於垃圾回收機制的引入,得到了很好的解決。所以,Java中的記憶體洩漏,主要指的是第二種情況。

    可能光說概念太抽象了,大家可以看一下這樣的例子:

1 Vector v=new Vector(10);
2 for (int i=1;i<100; i++){
3 Object o=new
 Object();
4 v.add(o);
5 o=null;
6 }

   
    在這個例子中,程式碼棧中存在Vector物件的引用v和Object物件的引用o。在For迴圈中,我們不斷的生成新的物件,然後將其新增到Vector物件中,之後將o引用置空。問題是當o引用被置空後,如果發生GC,我們建立的Object物件是否能夠被GC回收呢?答案是否定的。因為,GC在跟蹤程式碼棧中的引用時,會發現v引用,而繼續往下跟蹤,就會發現v引用指向的記憶體空間中又存在指向Object物件的引用。也就是說盡管o引用已經被置空,但是Object物件仍然存在其他的引用,是可以被訪問到的,所以GC無法將其釋放掉。如果在此迴圈之後,Object物件對程式已經沒有任何作用,那麼我們就認為此Java程式發生了記憶體洩漏。

    儘管對於C/C++中的記憶體洩露情況來說,Java記憶體洩露導致的破壞性小,除了少數情況會出現程式崩潰的情況外,大多數情況下程式仍然能正常執行。但是,在移動裝置對於記憶體和CPU都有較嚴格的限制的情況下,Java的記憶體溢位會導致程式效率低下、佔用大量不需要的記憶體等問題。這將導致整個機器效能變差,嚴重的也會引起丟擲OutOfMemoryError,導致程式崩潰