2015-11-13 29 views
4

在VisualVM中研究我的應用程序的行爲時,我遇到了這個問題並感到困惑,我認爲執行垃圾收集的JMX調用與調用System.gc()具有相同的功能,但是在我嘗試過的所有環境中, JMX調用總是導致堆使用率較小,然後調用System.gc(),功能上有什麼區別?JMX垃圾回收和System.gc()之間的區別?

enter image description here

您可以在最後一滴看到 - 我手動點擊執行GC按鈕,我的使用率降到低一點,然後它已經與正規系統集合。想一想爲什麼會這樣?

我已經在多個環境中嘗試了這一點,將集合留給系統並手動調用System.gc(),每次JMX調用都會清除更多。

正如你所張貼的圖片中看到,系統垃圾收集運行時,JMX調用只是清除,問題是這兩個調用之間的區別?

+0

這取決於你的應用程序的使用和對象分配。如果您的應用程序中生成的很多短期對象沒有收集到,儘管頻繁的GC不會發生,因爲GC本身是開銷/停止世界。所以如果您手動執行GC,則可以清除這些對象。 –

+0

用於'System.gc()'的JavaDoc:「調用gc方法**建議** Java虛擬機花費大量的工作來回收未使用的對象,以便使其當前佔用的內存可供快速重用。在這個方法調用中,Java虛擬機已經盡了最大努力**從所有被丟棄的對象中回收空間。「在實踐中,如果Java認爲結果不值得這項工作,它甚至可能決定什麼也不做。 「強制」的jmx調用可能會強制GC盡其所能。取決於實際的代碼。 –

+0

@tb,如果我的問題不清楚,我很抱歉,爲了更好地解釋我自己,我稍微編輯了一下。您可以在發佈的圖像中看到正在定期調用'System.gc()'調用,JMX調用結束時我的堆使用率降至接近0;問題是系統垃圾收集和JMX垃圾收集有什麼區別?似乎有不同的功能。 –

回答

4

這必須是間接的(由於它在程序執行或一些類似的因素被稱爲在不同的點) - 太陽的實施MemoryMXBeansun.management.MemoryImpl

public void gc() { 
    Runtime.getRuntime().gc(); 
} 

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/management/MemoryImpl.java#MemoryImpl.gc%28%29

System.gc()

public static void gc() { 
    Runtime.getRuntime().gc(); 
} 

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/System.java#System.gc%28%29

因此,建議垃圾收集的兩種方法之間確實沒有功能差異,唯一的區別在於何時以及從哪個線程調用它。

+0

嗯,有趣。我將不得不在其他一些Java小程序上嘗試一下。對於我來說,在這個應用程序的多次試驗中,我總是看到上述行爲,這似乎很奇怪。謝謝你。 –

0

一般情況下,MemoryMXBean.gc()只是調用System.gc()。

MemoryMXBean.gc()

空隙GC()運行垃圾收集器。調用GC()是有效 等同於調用:System.gc()的另請參見:System.gc()的

http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html

System.gc()的

public static void gc()運行垃圾回收器。調用gc 方法建議Java虛擬機花費努力去回收未使用的對象,以便使它們當前可用的內存快速重用。當控制從方法 調用返回時,Java虛擬機已盡最大努力從所有丟棄的對象中回收空間 。

呼叫系統。GC()是有效地等效於調用:

調用Runtime.getRuntime()GC()另請參見:Runtime.gc()

http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#gc()

Runtime.gc()

public void gc()運行垃圾回收器。調用此方法 建議Java虛擬機花費大量時間去回收未使用的對象,以便使其當前佔用的內存快速重用。當控制從方法調用 返回時,虛擬機已盡最大努力回收所有丟棄的對象。名稱gc代表「垃圾回收器」。即使未明確調用gc方法,虛擬機器也會根據需要自動執行此回收過程,即在 單獨的線程中執行此回收過程。

System.gc()方法是調用此方法的傳統方便手段。

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#gc()