首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JVM 調優實戰:從 Full GC 困境到效能優化之路

     編輯:Java 綜合教學

JVM 調優實戰:從 Full GC 困境到效能優化之路

俗話說技多不壓身,當年苦讀《深入理解 JVM》並整理筆記,如今終派上用場。筆記參考:https://www.cnblogs.com/syjkfind/p/3901774.html

現象

用戶操作數據導出時頻繁卡頓,後台大內存定時任務觸發時同樣發生。JVM 參數屬於常規合理配置。

排查思路

  • GC 日誌顯示頻繁 Full GC,Tomcat 日誌散落大量異常堆棧。
  • 結合代碼熟悉度,發現觸發時刻正在執行大數據量查詢並裝載入 JVM,方法調用深、臨時變量多。

深度分析

  1. Minor GC 極頻繁,耗時極短非核心問題,觸發原因多為新生代分配失敗。
  2. 偶發 System.gc(),耗時約 1 分鐘。代碼無顯式調用,基本鎖定為 JMX/RMI 監控觸發。可添加 -XX:+DisableExplicitGC 禁用。
  3. 頻繁 Promotion Failed,即 Minor GC 時 Survivor 空間不足導致對象提前進老年代,老年代又不足觸發 Full GC,耗時約 3 分鐘。解決方向:增大 Survivor 或 移除 Survivor 擴大老年代。關鍵參數:
    -XX:SurvivorRatio=32        # 單個 Survivor 佔年輕代 1/34
    -XX:OldSize=60M               # 老年代初始大小
    -XX:MaxTenuringThreshold=15   # 經歷 15 次 Minor GC 仍存活則晉升老年代
    
  4. 頻發 Concurrent Mode Failure,CMS 並發收集期間老年代空間不足,退化為 Serial Old 串行收集,停頓約 5 分鐘。成因包括浮動垃圾過多、CMS 自身佔用堆、老年代碎片化。調優參數:
    -XX:CMSInitiatingOccupancyFraction=80  # 老年代 80% 觸發 CMS
    -XX:+UseCMSCompactAtFullCollection     # Full GC 時壓縮碎片
    -XX:CMSFullGCsBeforeCompaction=5       # 每 5 次 Full GC 壓縮一次
    
  5. 異常過多導致 Promotion Failed:參考文章 過長異常堆棧影響 GC。專案曾關閉 -XX:-OmitStackTraceInFastThrow 導致重複異常生成完整堆棧,佔用大量臨時對象。需權衡調試需求與 GC 壓力。

解決之道

調優參數可緩解症狀,但代碼設計才是根源:缺乏多級緩存、萬條數據無分頁全載入、隱藏切面塞滿異步隊列。初期享受框架便利忽視設計,如今需償還技術債。

短期內加機器、剝離大任務最見效;中長期應:整理異常體系、強制業務分頁、封裝分頁查詢框架、引入二級集群緩存。長遠看須回歸 Spring 主流棧、邁向服務化,但那意味著重寫業務代碼。

若堅持調優,建議 Dump 堆深度分析。主觀上啟用快拋、Full GC 後碎片整理、增大 Survivor較有針對性;CMSInitiatingOccupancyFraction 等精細參數需量化分析後再定。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved