2013-03-29 67 views
6

我目前正在運行一個應用程序,它需要最大堆大小爲16GB。應用程序中的長GC暫停

目前我使用下面的選項來處理垃圾收集。

-XX\:+UseParNewGC, -XX\:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=50, -XX\:+DisableExplicitGC, -XX\:+PrintGCDateStamps, -XX\:+PrintGCDetails, -Xloggc\:/home/user/logs/gc.log 

然而,我注意到,在一些垃圾收集,應用程序鎖定了幾秒鐘,然後進行 - 這是完全不能接受的,因爲它是一個遊戲服務器。

的使出從我的垃圾收集日誌可以發現here

什麼,我應該爲了減少這些長暫停更改的任何意見,將不勝感激。

+4

我相信這就是爲什麼很多人喜歡C++對Java的實時遊戲的原因之一。但不要拿*我的*字...... – Mysticial

+0

你可以提供一些具有長期gc暫停的特定行嗎?而不是期望讀者通過日誌文件尋找 – noahlz

+0

行,我更喜歡使用超過1 GB的堆內存。關閉堆內存更難編碼,但對GC暫停時間影響不大。 –

回答

4

任何意見我應該改變,以減少這些長時間停頓將不勝感激。

很可能CMS CMS無法跟上系統產生的垃圾數量。但是GC必須執行的工作實際上更接近於與您的系統保留的非垃圾量有關。

所以......

  • 儘量減少你的應用程序的實際內存使用量;例如不要緩存這麼多東西,或者減少你的「世界」的大小。
  • 嘗試降低應用程序生成垃圾的速度。
  • 升級到具有更多內核的機器,以便在需要時有更多內核可用於運行並行GC線程。

要Mysticial:

是在事後,這可能是更好地實現服務器在C++中。但是,我們對「遊戲」一無所知。如果涉及到複雜的異構數據結構複雜的世界模型,然後實現它的C++ 可能意味着你替換服務器崩潰的所有時間的問題「GC暫停」問題,因爲它管理的方式問題其數據結構。

+0

我不是故意打擊Java。對於不同的事情,C++和Java只是不同的工具。 – Mysticial

+0

服務器運行的遊戲是'我的世界',如果這有幫助的話。 – Gontroller

+3

啊...基本上,你的問題是關於如何調整Minecraft。根本不是一個編程問題。你會在我認爲的Minecraft formums上得到更好的答案。 –

0

您正在使用哪個版本的java? http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html 爲了更好地儘量減少在class.It使用實例變量的將是更好的對局部變量進行比實例變量下,它可以幫助在程序退出前獲得從同步的性能和安全problem.In操作結束如果您使用實例變量,則始終重置使用的變量,並在需要時重新設置。它有助於提高性能。除了Java版本之外,還實現了一個好的垃圾收集策略。如果可行的話,遷移到新版本會更好。 此外,您還可以通過VisualVm監視垃圾收集器的暫停時間,並且可以在執行更多垃圾回收時獲得更多信息。

2

看着你的日誌,我沒有看到任何長時間的停頓。但年輕的GC非常頻繁。雖然促銷率很低(大多數垃圾由年輕的GC清除,因爲它應該)。同時您的舊空間利用率很低。

順便說一句我們在談論我的世界服務器?

要減少年輕GC的頻率,您應該增加其大小。我建議先從-XX:NewSize=8G -XX:MaxNewSize=8G

對於這樣大的年輕空間,你也應該減少生存空間大小-XX:SurvivorRatio=512

GC優化是試錯的路徑,所以你可能需要一些更多的迭代和調整。

您可以在萬畝博客找到幾個有用的文章