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

Tomcat 記憶體溢出完整分析:Heap、PermGen/Metaspace、GC 機制、JVM 參數調優與監控工具

     編輯:Java 程式設計入門

一、JVM 記憶體區域圖解


+-------------------------+
|       Heap (堆)         |  ← 開發人員管理,GC 主戰場
|  +-------------------+  |
|  | Young Gen (新生代) |  |  Eden + S0 + S1
|  | Old Gen (老年代)   |  |  長期存活物件
|  +-------------------+  |
+-------------------------+
|     Non-Heap (非堆)     |  ← JVM 內部使用
|  +-------------------+  |
|  | Metaspace (元空間) |  |  類別元資料(JDK 8+ 取代 PermGen)
|  | Code Cache        |  |  JIT 編譯代碼
|  +-------------------+  |
+-------------------------+

二、兩大 OOM 類型與對策

1. java.lang.OutOfMemoryError: Java heap space

  • 原因:物件過多、記憶體洩漏、-Xmx 設定過小
  • 參數:-Xms 初始堆、-Xmx 最大堆(建議設相同值避免震盪)
  • 新生代:-Xmn 或 -XX:NewRatio(建議 1:2 或 1:3)

2. java.lang.OutOfMemoryError: PermGen space (JDK 7-) / Metaspace (JDK 8+)

  • 原因:載入過多類別(大量 JSP、第三方 Jar、熱部署未清理)
  • JDK 7:-XX:PermSize=128m -XX:MaxPermSize=256m
  • JDK 8+:-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m
  • 類別卸載需觸發 Full GC,建議啟用 -XX:+CMSClassUnloadingEnabled (CMS) 或 G1 預設支援

三、GC 觸發條件與排查

  • Minor GC:Eden 滿 → 清理新生代
  • Major/Full GC:Old Gen 滿、Metaspace 滿、System.gc()、堆內存不足連續 GC 失敗
  • 危險訊號:98% 時間在 GC 且釋放 < 2% 堆 → 拋 OOM

四、生產環境建議參數模板(8G 實體記憶體範例)

# Linux: $CATALINA_HOME/bin/setenv.sh
export JAVA_OPTS="-server \
-Xms4g -Xmx4g \
-XX:NewSize=1g -XX:MaxNewSize=1g \
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/opt/tomcat/logs/heapdump.hprof \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps \
-Xloggc:/opt/tomcat/logs/gc.log"

五、關鍵參數說明

參數建議值說明
-Xms / -Xmx實體記憶體 50%-70%設相同避免伸縮
-Xmn堆 1/3 ~ 1/4新生代過大導致 Old Gen 過小觸發頻繁 Full GC
-XX:SurvivorRatio8 (預設)Eden : Survivor = 8 : 1 : 1
-XX:+UseG1GCJDK 9+ 預設大堆、低延遲首選
-XX:MaxGCPauseMillis100-200msG1 目標停頓時間
-XX:+HeapDumpOnOutOfMemoryError必開OOM 時自動產生堆轉儲檔

六、效能監控工具

  • JVisualVM / JConsole:JDK 內建,連線監控堆、執行緒、GC
  • JProfiler / YourKit:商業級,記憶體洩漏分析、CPU 剖析
  • Arthas / async-profiler:線上診斷、火焰圖、類別載入追蹤
  • Prometheus + Grafana + JMX Exporter:生產級監控儀表板

七、常見記憶體洩漏模式

  1. 靜態集合持有大量物件未清理
  2. ThreadLocal 未 remove()(執行緒池場景)
  3. 資料庫連線/Statement/ResultSet 未關閉
  4. 監聽器/回調未解除註冊
  5. 熱部署導致類別載入器無法回收(需配置類別卸載)

八、總結

Tomcat OOM 核心在於堆與元空間大小規劃、GC 策略選型、洩漏預防。建議:

  1. 依實體記憶體設定 -Xms/-Xmx、Metaspace
  2. 啟用 G1GC、堆轉儲、GC 日誌
  3. 定期用 JVisualVM/Arthas 檢視老年代佔用趨勢
  4. 代碼層面落實資源關閉、ThreadLocal 清理、靜態集合弱引用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved