2013-02-20 52 views
0

我想了解我的下面的書面代碼如何工作和輸出。瞭解JVM GC

public static void getRunTimeMemoryConsumption(){ 

List<Integer> array = new ArrayList<Integer>(); 
for(int i = 0 ; i < 100000 ; i++){ 
    array.add(i); 
} 

List<Integer> array1 = new ArrayList<Integer>(); 
for(int i = 0 ; i < 100 ; i++){ 
    array1.add(i); 
} 

Runtime rt = Runtime.getRuntime(); 

//Run the GC 
rt.gc(); 

long memoryFreed = rt.totalMemory() - rt.freeMemory(); 
System.out.println("Memory freed in Mbytes :: " + memoryFreed/(1024)); 

} 

當我運行這個代碼時,它總是給我132KB作爲輸出(9/10運行)。 但是,如果我刪除rt.gc()調用,則會在輸出語句中釋放更多釋放的內存(> 100 MB)。請幫我理解java Runtime的這種行爲。

在此先感謝。

回答

2

我不完全確定你在嘗試什麼。

您不計算釋放了多少內存,您正在計算rt.totalMemory() - rt.freeMemory(),即使用了多少內存。考慮到這一點,你得到的結果很有意義,沒有垃圾回收,在gc之後使用更多的內存。爲了找出釋放了多少內存,應該在調用垃圾回收器之前和之後比較rt.totalMemory() - rt.freeMemory()

另外,放入for循環列表中的整數不適合垃圾回收,因爲它們是活動對象(即列表)的引用。不知道什麼是垃圾收集,因爲我沒有看到你的程序的其餘部分,但你應該修改你的測試,以便在垃圾收集的時候你有沒有被活動對象引用的對象。

+0

只是爲了記錄,由於ArrayLists的大小調整,可以收集垃圾的是丟棄的數組,因爲它們沒有按預期的大小進行預分配。 – 2013-02-20 22:55:25

+0

哦,是的,你是對的。沒想到那個... – pushy 2013-02-21 08:39:46

0

此處的垃圾收集不會真的刪除任何東西,因爲您沒有任何超出範圍的對象。該方法範圍這兩個列表,以便它們都可以在垃圾回收調用後仍可訪問。垃圾收集是一項通常在java中計劃的任務,因此它可以在任何時候在理論上運行。這意味着這裏的行爲實際上是好的,因爲你不希望垃圾收集銷燬仍在範圍內的對象(就像你在這裏)。

2

您應該在rt.gc()之前和之後比較rt.freeMemory()。你的表情打印使用過的內存。這就是爲什麼這些值與你所期望的相反。

0

看起來你的內存花費較少,因爲它花費在由rt.gc()調用的垃圾回收器活動上。其實rt.gc()不會釋放爲你的數組分配的內存。如果要查看GC釋放了多少內存,則應在getRunTimeMemoryConsumption()方法之外進行計數,或者在測量之前將數組指定爲null。