2012-04-06 112 views
1

我的代碼下面的一段:Java垃圾收集和空

List<String> list = new ArrayList<String>(); 
    // WeakReference<List> wr = new WeakReference<List>(list); 
    System.out.println(" before tot memory... " + Runtime.getRuntime().totalMemory()); 
    System.out.println(" before free memory... " + Runtime.getRuntime().freeMemory()); 
    for(int i =0; i<100; i++) 
    list.add(new String("hello")); 
    //System.gc(); 
    list = null; //forcefully end its life expectancy 
    System.out.println(" after tot memory... " + Runtime.getRuntime().totalMemory()); 
    System.out.println(" after free memory... " + Runtime.getRuntime().freeMemory()); 
    System.out.println(" after memory used ... " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); 
    // System.out.println(" weak reference " + wr.get()); 

當我運行上面的代碼,我可以看到的空閒內存是361064(在我的系統,但是這個值可能不同)

但是當我用System.gc()和註釋列表= null運行上面的代碼時,我可以看到我的可用內存即將到來(在這種情況下爲160944)小於上述測試用例。在這兩種情況下,對象都從內存中移除,但爲什麼這些值是不同的。

+1

'new String(「hello」)'創建兩個對象。這個構造函數不應該被使用。嘗試'list.add(「hello」)' – 2012-04-06 08:34:43

+0

@ajozwik我不會說'從來沒有'。它有一些有效的用例。這就是它存在的原因。 – EJP 2012-04-06 09:45:22

回答

1

list = null;取消任何引用將自動導致垃圾回收。當您對此行發表評論時,參考列表仍處於活動狀態,則即使您致電System.gc()它也不會被垃圾收集。

當您明確呼叫gc()時,已被取消的引用或超出範圍的引用僅被垃圾收集。

+0

如果是這樣的話,System.gc()的用法是什麼。在這種情況下,它可以被真正使用:)另外,如果list = null註釋並運行應用程序,System.gc()調用會執行什麼操作,因爲它可以釋放或釋放一些東西 – UVM 2012-04-06 07:08:20

+0

@UNNI gc()將釋放所有那些引用被取消或超出範圍。它永遠不會清除那些活動的引用。 – 2012-04-06 07:16:28

+0

在上面的測試用例中,當您僅使用System.gc()運行時,它釋放了一些內存或某個「值」。在這種情況下,釋放該值的原因是該列表仍處於活動狀態,它不會被放棄。 – UVM 2012-04-06 07:25:25

0

GC通過查看內存中的所有對象以查找程序中的任何objects which are no longer being referenced。這些未使用的對象可以被刪除,以便爲新的內存對象騰出空間。

因此,如果任何對象仍然被轉介,即使您撥打System.gc()也無法收集垃圾。如果可以在代碼中引用對象,如何收集垃圾對象?

通過調用list = null,由list變量引用的對象不能再被引用,因此它有資格獲取垃圾回收。