我們最近開始偶爾使用有關「java.lang.OutOfMemoryError:請求8589934608字節的Chunk :: new。Out of swap space?」消息開始崩潰的應用程序。Java JIT編譯器導致OutOfMemoryError
我環顧四周,在網絡上,到處都建議只限於
- 恢復到以前的版本的Java
- 小提琴與內存設置
- 使用客戶端而不是服務器模式
恢復到以前的版本意味着新的Java有一個錯誤,但我沒有看到任何跡象。記憶根本不是問題;服務器有32GB可用,並且Xmx設置爲20,而Xms是10.我看不到剩餘12GB的JVM耗盡(減少給予機器上其他幾個進程的量)。由於應用程序和環境的特性,我們堅持使用服務器模式。
當我查看應用程序的內存和CPU使用情況時,我發現整天的內存使用量不斷增加,但在使用之前突然發生CPU使用率高達100%,內存使用量從X增加到X + 2GB,到X + 4GB,到(有時)X + 8GB,到JVM死亡。這似乎是在JIT編譯中可能發生循環重複數組大小調整。
我現在看到上述8GB請求和16GB請求發生錯誤。所有時候,這種情況發生時編譯的方法都是一樣的。這是一個簡單的方法,它具有非嵌套循環,沒有遞歸,並且使用方法直接返回靜態成員字段或實例成員字段,計算量很少。
所以我有2個問題:
- 沒有任何人有什麼建議嗎?
- 我可以測試在測試環境中是否存在編譯此特定方法的問題,而不運行整個應用程序,直接調用JIT編譯器?或者我應該啓動應用程序,並告訴它編譯方法後小得多的調用計數(如2),迫使它編譯方法幾乎立即而不是在一天的隨機點?
@StephenC
JVM是1.6.0_20(先前1.6.0_0),在Solaris運行。我知道這是由於幾個原因導致問題的彙編。
- 在導致它的秒
ps
示出與對應於編譯器線程(從jstack)ID的Java線程佔用了100%的CPU時間 jstack
示出了問題是JavaThread "CompilerThread1" daemon [_thread_in_native, id=34, ...]
jstack
中提到的方法總是一樣的,而且是我們寫的。如果您看到示例jstack
輸出,您將知道我的意思,但出於顯而易見的原因,我無法提供代碼示例或文件名。我會說這是一個非常簡單的方法。 Essentiall少數空檢查,2 for循環進行平等檢查並可能分配值,以及一些簡單的方法調用之後。總共可能有40行代碼。
儘管應用程序每天運行並且每天都重新啓動,但該問題在兩週內發生過兩次。此外,這些應用程序在這些時間都沒有承受重負。
如果您說出您正在使用的JVM版本和補丁級別(以及之前的內容)以及您的操作系統/硬件平臺是什麼,這將會很有幫助。另外,爲什麼你在JIT編譯期間得出結論:問題是如何發生的,你如何計算出正在編譯的方法......以及方法的代碼是什麼樣的。 – 2010-08-11 08:59:28
您是否找到滿意的解決方案? – 2015-01-01 17:48:00
對不起*非常*遲到的回覆 - 我已經標記了答案 – Phil 2015-03-15 12:06:03