簡體   English   中英

分析和避免Java中的完整GC

[英]Analyzing and avoiding a Full GC in Java

我正在開發一個時間緊迫的應用程序,每次迭代的時間上限為40毫秒。 如果僅超過一次時間限制,則終止應用程序並結束游戲。 應用程序本身沒有問題,不會超過40 ms,有時是垃圾收集器超出了限制。

通過結合使用對象池和工廠模式,我成功地消除了對垃圾收集的需求,並且應用程序實現了穩定的17毫秒迭代時間,包括小規模的GC運行,但在應用程序啟動后僅進行了10次至20次迭代之后,只有一個完整的GC發生超過40毫秒並殺死了我的應用程序。

我的問題是,我如何分析導致這一完整GC的確切原因? 我大量使用了jvisualvm來分析運行時和內存占用,這對識別需要緩存的對象很有幫助。 但是在這種特殊情況下,我無法使用它,因為完整的GC發生了很長時間,然后才可以按jvisualvm中的右按鈕。 有沒有辦法以編程方式生成堆轉儲?

我會使用商業內存分析器,例如YourKit。 您可以從其中的大部分時間獲得免費的評估許可證,以解決您的問題。 ;)

我發現VisualVM的一個問題是,當您最小化對象創建時,最大的內存生產者是Memory Profiler本身。 商業分析器沒有問題,因為它們使用了堆內存。

我會看到您可以采取什么措施來進一步減少垃圾。 17 ms仍然很長一段時間,您也可以考慮對此進行CPU分析。 CPU分析器在大約半毫秒內有用。 低於此值時,您需要使用自己的精確時間以及一些反復試驗的時間。

我發現有用的事情是在完成CPU配置文件和內存配置文件后,立即運行它們,您將獲得關於可以改進的更多建議。

如果減少產生的垃圾量並增加伊甸園的空間,則每天可能只收集一次次要的垃圾。

http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html

您是否聽說過HeapDumpOnCtrlBreak; 試試這個連結

或者使用

jmap -dump:format=b,file=<filename.hprof> <pid>

大多數情況下,JVM上的垃圾回收是一個巨大的優勢,但是主要的缺點(如您所知)是,它有時會導致無法預料的GC暫停。

標准JVM適用於軟實時(當您可以容忍偶爾的暫停時),但不適用於硬實時(即,超出給定容限的任何暫停導致錯誤/失敗)

一些有用的建議是:

  • 如果可以,請移至專用的實時JVM(例如Zing JVM )。 這是通過Java可靠地獲取實時行為的最佳方法
  • 使用低延遲的庫文件(例如Javolution) -通過為數據結構提供非常低的對象分配率(從而減少GC開銷),可以大有幫助

您可以嘗試使用jprofiler的評估版,它使您可以使應用程序等待分析器啟動。 它不影響堆內存,通常它是一個功能強大的探查器,具有良好的IDE集成和一鍵式設置。

但是,由於您說無法控制堆大小或gc設置,因此您將無能為力。 在啟動時加載類會產生一些需要收集的垃圾。

我可能會問:這是家庭作業還是僅僅是某種競賽/挑戰?

您是否嘗試過調整垃圾收集參數? 如果您的計算機上有足夠的RAM和一個以上的內核,那么您應該能夠利用並行垃圾收集。 默認情況下,在Java 1.6 JVM上處於啟用狀態 基本上,如果您確保年輕一代足夠大,以使對象永遠不會提升為老一代(以串行方式收集)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM