2011-11-25 63 views
1

當在下面顯示的類中執行i3 = null;時,有四個對象可以垃圾回收。我添加了評論來解釋我是如何得到這個答案的。我的推理是否正確?OCPJP考試的垃圾回收模擬

public class Icelandic extends Horse{ 
    public void makeNoise(){ 
     System.out.println("vinny"); 
    } 

    public static void main(String args[]){ 
     /** 
     * 2 objects created 
     */ 
     Icelandic i1 = new Icelandic(); 

     /** 
     * 2 objects created 
     */ 
     Icelandic i2 = new Icelandic(); 

     /** 
     * 2 objects created 
     */ 
     Icelandic i3 = new Icelandic(); 

     /** 
     * i3 is now pointing at i1, original Icelandic() referred to by i3 now 
      * has no reference - 2 objects now have no reference 
     */ 
     i3 = i1; 

     /** 
     * i3 is now pointing at i1, original Icelandic() referred to by i1 now 
      * has no reference - 2 objects now have no reference 
     */ 
     i1 = i2; 

     /** 
     * Total of six objects created, 4 objects no longer have a reference so 4 
      * can be garbage collected. 
     * 
     * Setting to null below doesn't make any difference to garbage collector 
      * as objects now do not have a reference 
     */ 
     i2 = null; 
     i3 = null; 
    } 
} 

interface Animal { 
    void makeNoise(); 
} 

class Horse implements Animal{ 
    Long weight = 1200L; 

    public void makeNoise() { 
     System.out.println("whinny"); 
    }  
} 
+1

我認爲在創建「冰島」時創建一個對象更合適。即使類本身是繼承的。 – 2011-11-25 16:36:38

+0

類和對象之間有區別。當你從一個類繼承並創建一個對象時,這將只是一個對象。 –

+0

如果你計算層次結構(我猜想它是錯誤的),你還應該包含Object,因爲每個類都會擴展它。 – mishadoff

回答

12

這是你的程序的步驟:

Icelandic i1 = new Icelandic(); 
    Icelandic i2 = new Icelandic(); 
    Icelandic i3 = new Icelandic(); 

enter image description here

i3 = i1; 
    i1 = i2; 

enter image description here

i2 = null; 
    i3 = null; 

enter image description here

因此,最後一個圖表得出結論,只有2個對象已準備好進行垃圾回收。 我希望我很清楚。您可以將對象名稱視爲對象的引用。

編輯:

如所述通過BalusC,龍重量= 1200L還對象。因此,對於i1和i3,每個對象有2個符合條件或垃圾回收。所有4個對象都符合條件或垃圾收集。

+4

優秀的演示文稿。但我認爲你必須考慮這個「長重= 1200L」,以及SCJP問題中提到的* actual *答案似乎是4個符合GC的條件。 – BalusC

+0

@BalusC長體重對垃圾收集過程有什麼影響?我的意思是隻有一個副本是爲馬,動物和冰島在一個對象中創建的。你能詳細說明一下嗎? – prap19

+0

@BalusC是正確的,當我最初閱讀這個問題時,我沒有一路向下滾動(我只在編輯過程中注意到它)。由於每個冰島IS-A馬,每個人都有自己的份量。由於它是大寫字母L,所以重量是一個對象。 – Pops

1

根據經驗,一個非常簡單的規則,在java中的對象可以收集垃圾,如果程序的行爲不會改變如果對象的所有字段複製到本地變量(一個優化的程序轉換)和所有的參照對象被設置爲null。

引用「Java虛擬機規範」

12.6.1實施定稿 每個對象的特徵可在於兩個屬性:它可以是可到達的,終結器可達的,或不可達,並且它也可以是未確定的,可終結或最終確定。

可到達對象是可以從任何活動線程進行任何潛在的持續計算中訪問的任何對象。優化程序的轉換可以設計爲將可達到的對象數量減少到小於天真被認爲可達的對象數量。例如,編譯器或代碼生成器可以選擇將不再用於空的變量或參數設置爲使得此類對象的存儲器可以更快地被回收。

討論

如果在對象的字段中的值被存儲在寄存器發生的另一個例子。程序然後可以訪問寄存器而不是對象,並且再也不訪問對象。這意味着該對象是垃圾。

所以你的情況,因爲沒有引用任何Icelandic對象的取消引用,所有的人都可以被垃圾立即收集。由於沒有任何內容取消i1i3,所以優化編譯器可以自由地將i3 = new Icelandic()之後的所有內容作爲無操作並立即收集所有六個對象。