天天看點

java記憶體配置設定問題

java的記憶體配置設定分為兩種基本資料類型。和對象類型。對8類基本資料類型,直接在棧上配置設定。對于對象既在棧上配置設定,也在堆上配置設定,在棧上配置設定引用的位址,在堆上配置設定new出來的對象。通過棧上配置設定的位址找到堆上new出來的對象。這些基礎知識基本上都很簡單,其實通過java的記憶體配置設定。我們可以很清楚的了解java裡面非常著名的垃圾回收機制。java的垃圾回收機制,隻回收堆上面的記憶體。不回收棧上面空間。很多書上都說,java回收機制是通過判斷堆上的對象是否被引用。是否是有棧上的句柄指向堆上的對象,如果沒有。java就會自動回收。舉一個網上記憶體溢出非常多的例子來說:

public class out{
  public static void main(String args[]){
       List v=new ArrayList();
       for(int i=0;i<4000000;i++){
          Object o=new Object();
          v.add(o);
         o=null;//強制釋放記憶體
       } 
 }
} 
           

我個人認為。最後令o=null就已經釋放了o在堆上占據的記憶體。我現在的疑問是v裡面有4000000個 object,在add進去後。堆記憶體上肯定還存在4000000個object。我個人覺得最後一句o=null沒有什麼作用。本人做了個測試。在i=5089378時,記憶體溢出。如果我屏蔽最後那句o=null 時測試還是i=5089378時記憶體溢出。這好像證明最後那句強制釋放記憶體沒有啥作用。我現在最大的疑問是在list add進去對象後的記憶體配置設定情況。到底是怎樣。本人非常疑惑。本人對于for循環裡面new對象也有很大的疑問。

for(int i=0;i<4000000;i++){
          Object o=new Object();
          v.add(o);
            } 
           

如果你在程式裡面寫這樣的語句:

Object o=new Object();

Object o=new Object();

Object o=new Object();

不用想肯定不會通過編譯。但是在for循環裡面 new無數個都可以。本人的了解就是for循環裡面的循環new對象後,每次新new 的時候上個new出來就會被垃圾自動回收。但是這個引用還存在啊,這麼會被自動回收了, 本人今天突然覺悟,發現自己想通了,原來是局部變量,和全局變量的原因。

-- 局部變量 new 出來時,在棧空間和堆空間中配置設定空間,當局部變量生命周期結束後,棧空間立刻被回收,堆空間區域等待GC回收;

在程式:

public class out{
  public static void main(String args[]){
       List v=new ArrayList();
       for(int i=0;i<4000000;i++){
          Object o=new Object();
          v.add(o);
          o=null;//毫無意義
       } 
 }
} 
           

o是局部變量,new出來後,在作用域内,在棧空間,和堆空間配置設定。當離開循環,再次進入下一次循環,生命周期結束。棧上的引用空間,立刻被回收。但是在堆空間,new 出來的對象

還被v以用,是以垃圾回收,不會回收,其實本人一直對最後那句o=null很不解。有什麼必要嗎,垃圾回收立刻回收了棧空間的資料,還有必要嗎?畫蛇添足。搞的我一直暈頭轉向。其實這個程式的記憶體溢出是,v裡面放入了過多的object,而導緻的溢出。并不是什麼垃圾回收的問題。個人認為。呵呵!關于for循環裡面new對象的問題,同樣的道理,局部變量超過生命周期,自動回收,是以 不管你new多少個相同名稱的對象,它在确定的時刻,隻有一個引用在棧上。是以就不存在出現兩個相同名稱的引用。