jvmti_JVMTI标记如何影响GC暂停
jvmti
這篇文章分析了為什么Plumbr Agents在某些情況下以及如何延長GC暫停的時間。 對基本問題進行故障診斷揭示了有關在GC暫停期間如何處理JVMTI標記的有趣見解。
發現問題
我們的一位客戶抱怨說,附加了Plumbr代理后,應用程序的響應速度明顯降低。 通過分析GC日志,我們發現GC時間異常。 這是不帶Plumbr的JVM摘錄的GC日志:
這是附加了Plumbr Agent的:
2015-02-02T17:40:35.872-0200: 333.166: [Full GC (Ergonomics) [PSYoungGen: 524800K->0K(611840K)] [ParOldGen: 1194734K->1197253K(1398272K)] 1719534K->1197253K(2010112K), [Metaspace: 17710K->17710K(1064960K)], 1.9900624 secs] [Times: user=7.94 sys=0.01, real=1.99 secs]異常隱藏在經過的時間中。 實時時間是經過的實際時間。 如果您手里拿著秒表,那么實時將等于該數字。 用戶時間 (加上系統時間)是測量過程中消耗的總CPU時間。 如果多個內核上有多個線程,則該時間可能大于實時時間。 因此,對于并行GC,實時時間應大致等于(用戶時間/線程數)。 在我的機器上,該比率應該接近7,而沒有Plumbr Agent的情況下確實是如此。 但是使用Plumbr時,該比率大大下降。 絕對不行!
初步調查
有了這樣的證據,以下是最可能的假設:
但是,僅查看GC日志中的一行,就無法進行更狹窄的觀察,因此我們繼續進行可視化上述比率:
圖表上的下降恰好發生在Plumbr發現內存泄漏的那一刻。 根本原因分析過程中,GC可能會給GC帶來一些額外負擔,但永久影響GC暫停時間絕對不是我們為代理特意設計的功能。 這種行為有利于第一個假設,因為我們不太可能在運行時影響GC線程的數量。
創建一個隔離的測試用例花費了一段時間,但是在以下約束的幫助下,我們可以釘上它:
編譯了足夠小的測試用例后,可以放大根本原因檢測范圍。 合理的方法是打開和關閉Plumbr代理的各個功能,然后查看問題將在哪種配置下重現。
通過這種簡單的搜索,我們設法將問題定位到Plumbr Agent執行的單個操作。 JVMTI標記關閉后,問題消失了。 在分析gc根和引用鏈的路徑時 ,我們標記堆上的每個對象。 顯然,GC時間在某種程度上受我們生成的標簽的影響。
尋找根本原因
但是,尚不清楚為什么GC暫停會延長。 垃圾會被Swift收集,并且大多數帶標簽的對象應該符合GC的條件。 但是發現的是,存在大量活動集(這是內存泄漏的癥狀之一),其中保留了許多帶標簽的對象。
但是,即使對活動集中的所有對象都進行了標記,這也不應線性影響GC時間。 GC完成后,我們會收到有關所有已收集的標記對象的通知,但活動集不在這些對象之內。 這使人們想知道,HotSpot是否出于某種奇怪的原因在每個GC之后迭代所有標記的對象。
為了驗證要求,可以查看熱點源代碼。 經過一番挖掘之后,我們最終到達JvmtiTagMap :: do_weak_oops ,它的確對所有標簽進行了迭代, 并對所有標簽進行了一些不太便宜的操作。 更糟的是,該操作是順序執行的,并且不并行執行。 在每個垃圾回收之后找到調用此方法的調用鏈之后,解決了最后一個難題。 (為什么這樣做的方式以及它與弱引用的關系完全超出了本文的范圍)
在并行GC上運行并具有與串行運行相同的昂貴操作,一開始似乎是設計缺陷。 第二個想法,JVMTI的創建者可能從未期望有人標記所有的堆,因此從來沒有費心去優化此操作或并行運行它。 畢竟,您永遠無法預測人們將使用您設計的功能的所有方式,因此也許值得檢查Hotspot中的GC后活動是否也應該有機會使用現代JVM傾向于使用的所有gazillion內核??墒褂?。
因此,為了解決這個問題,我們需要清理不再需要的標簽。 修復它就像在我們的JVMTI回調之一中僅添加三行一樣容易:
+ if(isGenerated(*tag_ptr)) { + *tag_ptr = 0; + }瞧,一旦分析完成,我們幾乎和開始時一樣出色。 如下面的屏幕截圖所示,在發現內存泄漏期間仍然存在暫時的性能波動,并且在完成內存泄漏分析之后會略有惡化:
結語
現在,補丁已推出,并且解決了Plumbr檢測到泄漏后GC暫停時間受到影響的情況。 隨意去獲取更新的代理以解決性能問題。
作為一個總結,我建議您在使用廣泛的標簽時要格外小心,因為“便宜”的標簽會堆積在角落的箱子上,從而為性能的大幅下降奠定了基石。 為確保您沒有濫用標記,請翻轉– XX:+ TraceJVMTIObjectTagging的診斷選項。 它將使您能夠估計標簽映射消耗多少本機內存以及堆遍歷花費的時間。
翻譯自: https://www.javacodegeeks.com/2015/02/jvmti-tagging-can-affect-gc-pauses.html
jvmti
總結
以上是生活随笔為你收集整理的jvmti_JVMTI标记如何影响GC暂停的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos攻击有免费的吗(DDOS攻击有免
- 下一篇: 安卓锁屏解锁状态怎么录屏(安卓锁屏解锁)