2012-12-29 38 views
4

我不明白如何獲得此異常,而JVM使用的總內存(Runtime.totalMemory())大約是一半被分配(Runtime.maxMemory())。任何想法 ?Java:儘管有足夠的內存分配可用的「GC開銷超限」

Total Memory : 1708MB as returned by Runtime.getRuntime().totalMemory() 
Max. Memory : 3545MB as returned by Runtime.getRuntime().maxMemory() 

JRE : Java HotSpot(TM) 64-Bit Server VM : 1.6.0_29 (Linux) 
+0

對不起,在之前的回答中,我誤導了你,我誤讀了一些僅與RMI相關的信息。 – pcalcao

回答

1

如前所述pcalcao時,JVM是告訴你,這是花太多時間在垃圾收集上,並且做得不夠實際工作,所以它只是要擺脫困境。

這是一種安全閥,可以避免您實際上沒有用完內存的情況,但足夠接近以至於您確實沒有取得任何進展。 this answer有更多的細節,但我會提到一些可能適用於你的情況的東西:

這很可能發生,如果你SoftReference s緩存的東西 - 作爲堆向最大尺寸增長,這些引用被清除,並可能反覆重新生成(取決於您的密鑰循環是否觸及)它們,導致GC不斷髮生的不良行爲,但始終會恢復足夠的內存以繼續執行,因爲它可以清除一些軟引用 - 甚至JDK也會因爲它們在其類Locale中使用這種緩存而受到影響。

如果您確實想使用-XX:-UseGCOverheadLimit,則可以禁用此行爲。儘管如此,它指出的問題是真實的 - 您的運行時間花費不到實際工作的2%。

你在哪裏打印出這些記憶值?根據你的程序的結構,它可能會產生大量的垃圾,並在一些內部循環中使用大部分堆,但在你放置你的診斷輸出的地方,垃圾被回收。 -verbose:gc可以讓你更好地瞭解實際的GC行爲。

+0

沒有SoftReference;在這種情況下沒有緩存;一個單線程的處理分配...我真的需要RAM:沒有什麼可以釋放的。 –

+1

在一個寫得很好的應用程序中,你會得到這個錯誤是不尋常的,因爲你必須用很少的其他處理才能產生大量的對象來觸發它,或者可能有奇怪的大小世代。 -verbose:gc將成爲你的朋友,也許與jmap或jvisualvm結合使用。 – BeeOnRope

+0

更有可能我們得到錯誤的日誌信息;感謝您的意見我已經接受了回覆。你可能想知道Max。內存可能比OS中可用的大(JVM不檢查)。 –

相關問題