我正在研究一個應用程序,其目的是儘可能快地計算報表。如何找到哪個終結器耗時
我的應用程序使用了大量的內存;超過100 Go。
自我們上次發佈以來,我注意到一個很大的性能放緩。我的調查顯示,在計算過程中,我在40到60秒之間得到了很多垃圾回收! (JMC告訴我,他們是SerialOld,但我不知道它究竟意味着),當然,當JVM的垃圾收集,應用是絕對凍結
我現在調查這些垃圾收集的來源......這是一項非常艱苦的工作。
我懷疑,如果這些垃圾收集都這麼久了,那是因爲他們在finalize
功能花費很多次(我知道,所有的庫中,我們整合來自其他球隊,他們中的一些使用終結)
但是,我不知道如何對這個假設進行確認(或不確定)如何找到哪個終結器是耗時的。
我找了一個很好的工具,甚至是一個很好的方法
收集的數據正如你所看到的,我總是有很多「待終結」時,我有a 日誌舊垃圾
令人驚訝的是,當我使用JVisualVM時,上面的圖 定期從右向左滾動。當舊垃圾 觸發時,滾動停止(直到這裏,它看起來很正常,這是 世界末日)。然而,當突然滾動重新啓動,它 不是從舊垃圾的結束,而是從待定串行年底
這讓我覺得終結阻礙着JVM
有沒有人有一個交代這個?
非常感謝您 菲利普
'finalize'方法在垃圾回收期間不執行。 – apangin
當然?即使對於「SerializeOld」垃圾收集? 感謝您的回答 –
絕對。沒有Java代碼在非併發GC階段運行。僅GC *發現*可終結對象並將它們添加到隊列中。該隊列稍後由['Finalizer']處理(http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/8b04ee324a1a/src/share/classes/java/lang/ref/Finalizer.java# l186)與其他Java線程一起運行的Java線程。 – apangin