iT邦幫忙

2026 iThome 鐵人賽

0
Build on Google AI

把Google AI當夥伴打造個人高效Coding工作流系列 第 23 篇

第二十三天線上故障排查工具箱jstack/jmap/Arthas與OOM/CPU 100%實戰定位

  • 分享至 

  • xImage
  •  

一、 線上排查黃金原則:保護現場與最小衝擊

  • 保留第一現場:在重啟或隔離流量前,務必留下CPU、執行緒堆疊、GC Log與Heap Dump快照。
  • 生產防禦禁忌:
    • 嚴禁在尖峰流量直接執行jmap -dump:live:該指令會強迫JVM觸發一次 Full GC並程STW凍結進程;若Heap達十幾GB,系統可能瞬間停頓數分鐘導致服務斷線。
    • 容氣化防禦參數:所有Java容器與生產進程啟動時,必須預設加入:
      -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/dumps/dump.hprof

二、現代線上診斷神器:Arthas高頻指令
阿里巴巴開源的Arthas基於Java Agent與字節碼增強技術,免重啟直接Attach到運行進程中,是線上除錯的降維打擊武器:

  • dashboard:即時大盤儀表板,一屏掌握當前CPU、Memory各代空間、GC次數與執行緒排行榜。
  • thread -n 3:秒級定位CPU殺手,直接輸出目前吞噬CPU資源前三名的執行緒完整代碼堆疊與行號。
  • thread -b:一鍵找出死鎖鎖主,自動定位當前造成其他執行緒BLOCKED的持有鎖執行緒。
  • watch <全類名> <方法名> '{params, returnObj, throwExp}' -x 2:無侵入觀察線上方法的入參、返回值與拋出的異常,徹底告別「為了加 Log 排查而重新部署」。
  • trace <全類名> <方法名>:方法內部各步驟耗時剖析,精確定位哪一行 DB 查詢或外部呼叫造成慢請求(Latency)。

三、生產經典故障一:CPU 100%

  • 當告警響起伺服器CPU飆滿,標準排查四步驟:
    1.top:找到最高CPU的Java PID (假設 8888)
    2.top -Hp 8888:找到該進程內最高 CPU 的 OS 執行緒 TID (假設 8912)
    3.printf "%x\n" 8912:轉為 16 進位 (得 0x22d0,對應 jstack 的 nid)
    4.jstack 8888 | grep 0x22d0 -A 30:精確鎖定代碼行號

常見根本原因分類:
* 業務死迴圈
* 堆疊停留在自訂業務代碼

  • 頻繁FullGC導致的CPU震盪:
    • 抓出來的高CPU執行緒名稱為VM Thread或GC Thread(如 Gang worker)。
    • 此時問題的表象是CPU高,本質是記憶體不足(記憶體被塞滿,GC 執行緒瘋狂執行Full GC但回收不到空間,拼命空轉消耗 CPU)。

四、生產經典故障二:OutOfMemoryError
1.常見OOM類型與根因

  • java.lang.OutOfMemoryError:Java heap space:
    • 現象:堆積記憶體耗盡。
    • 主因:慢查詢一次性查出數百萬筆資料載入記憶體、靜態集合(如 static Map)快取無淘汰機制導致洩漏、連線物件(Connection/Stream)未正常關閉。
  • java.lang.OutOfMemoryError: Metaspace:
    • 現象:元空間(方法區)耗盡。
    • 主因:底層大量使用動態代理(CGLIB/ASM)、反射或熱部署,頻繁生成大量的動態 Class 未被卸載。
  • java.lang.OutOfMemoryError:Unable to create new native thread:
    • 現象:無法建立新的作業系統原生執行緒。
    • 主因:代碼中隨處new Thread()或誤用 Executors.newCachedThreadPool(),加上作業系統設定的max user processes(ulimit -u)限制被衝垮。
  • java.lang.StackOverflowError(屬於 Error):
    • 現象:執行緒調用棧深度超限。
    • 主因:方法無限遞迴呼叫、物件間循環依賴導致的toString() / hashCode() 彼此無限互呼。
  1. Heap Dump分析兩大利器
    拿到.hprof檔案後,離線放入分析工具排查:
  • Eclipse MAT (Memory Analyzer Tool):
    • 點擊Leak Suspects Report:自動分析出佔用最大記憶體的單一物件鏈。
    • 查看Dominatr Tree(支配樹):找出誰是佔用記憶體的根源巨獸。
    • 執行Path to GC Roots(選擇 exclude phantom/soft/weak references):追查該無用物件為什麼無法被GC回收,抓出背後長命的引用鏈條。
  • JProfiler/VisualVM:適合進行直觀的類別實例計數與記憶體消長比對。

上一篇
第二十二天堆積記憶體分代模型、GC Root可達性分析與G1/ZGC演進
系列文
把Google AI當夥伴打造個人高效Coding工作流 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言