Java 應用程式運行在 JVM (Java Virtual Machine) 之上,深入理解 JVM 內部運作機制是進行效能調優、排查 OOM、分析 GC 行為的前提。本系列第一篇系統梳理 JVM 核心組件、類別載入機制、執行引擎、記憶體區域劃分與垃圾回收基礎,為後續調優實戰打下堅實基礎。

| 區域 | 線程共享性 | 主要內容 | OOM 風險 |
|---|---|---|---|
| 堆 | 全線程共享 | 物件實例、陣列、字串常量池 (JDK 7+) | 高 - 主要調優目標 |
| 方法區 | 全線程共享 | 類別元資料、常量、靜態變數、JIT 編譯代碼 JDK 8+: Metaspace (本地記憶體) | 中 - 類別過多/動態代理 |
| Java 虛擬機棧 | 線程私有 | 棧幀 (局部變數表、操作數棧、動態連結、方法返回地址) | 低 - 遞歸過深/大量線程 |
| 本地方法棧 | 線程私有 | Native 方法調用狀態 | 低 |
| 程式計數器 | 線程私有 | 當前執行字節碼指令地址 | 極低 - 唯一不會 OOM 區域 |
┌─────────────────────────────────────────────┐ │ Heap │ ├──────────────────┬──────────────────────────┤ │ Young Gen │ Old Gen │ │ (新生代) │ (老年代) │ │ ┌─────┬───┬───┐ │ │ │ │Eden │S0 │S1 │ │ 長期存活物件 │ │ │ │Sur│Sur│ │ 大物件直接進老年代 │ │ └─────┴───┴───┘ │ │ │ Minor GC │ Major/Full GC │ └──────────────────┴──────────────────────────┘
Bootstrap ClassLoader (啟動類載入器) - rt.jar, 核心庫
↑
Extension ClassLoader (擴充類載入器) - jre/lib/ext
↑
Application ClassLoader (應用類載入器) - classpath
↑
Custom ClassLoader (自訂類載入器) - 熱部署、模組化、加密類
優勢:避免類別重複載入、保護核心 API 不被篡改、隔離不同模組依賴版本
| 模式 | 特點 | 適用場景 | ||
|---|---|---|---|---|
| 解釋執行 | 啟動快、無編譯開銷、逐條執行 | 啟動階段、冷代碼、一次性代碼 | ||
| C1 (Client Compiler) | 編譯快、優化較少、客戶端應用 | 啟動敏感、GUI 應用 | ||
| C2 (Server Compiler) | 編譯慢、深度優化、服務端應用 | 長期運行、高吞吐、計算密集 | ||
| 分層編譯 (預設) | 0-4 層級:解釋 → C1 → C1+Profiling → C2 | 平衡啟動速度與峰值效能 |
| 算法 | 原理 | 優點 | 缺點 | 適用區域 |
|---|---|---|---|---|
| 標記-清除 | 標記存活 → 清除未標記 | 實現簡單 | 碎片化、效率低 | 老年代 |
| 標記-整理 | 標記存活 → 壓縮到一端 | 無碎片 | 需移動物件、更新引用 | 老年代 |
| 複製 | 劃分兩塊 → 存活複製到另一塊 | 無碎片、分配快 | 浪費 50% 空間 | 新生代 |
| 分代收集 | 新生代用複製、老年代用標記-整理 | 綜合優勢 | 複雜度高 | 全堆 |
# 堆記憶體
-Xms4g -Xmx4g # 固定堆大小,避免震盪
-Xmn2g # 新生代大小 (隱含老年代 = 堆 - 新生代)
# Metaspace (JDK 8+)
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
# GC 選擇
-XX:+UseG1GC # G1 (JDK 9+ 預設)
-XX:+UseZGC # ZGC (JDK 11+ 實驗/生產就緒)
-XX:+UseShenandoahGC # Shenandoah (低延遲)
# GC 日誌 (JDK 9+ 統一日誌)
-Xlog:gc*:file=/logs/gc.log:time,uptime,level,tags:filecount=10,filesize=100m
# JIT 編譯
-XX:CompileThreshold=1000 # 觸發編譯的呼叫次數
-XX:+PrintCompilation # 列印編譯資訊
# 除錯診斷
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/dumps/
-XX:ErrorFile=/logs/hs_err_pid%p.log