Java 虛擬機(JVM)是 Java 跨平台、自動記憶體管理、高性能運行的基石。本文系統梳理 JVM 核心架構,涵蓋運行時數據區劃分、類加載子系統、執行引擎、記憶體模型演進(JDK 6/7/8/11+),配合圖解與參數調優指南,構建完整的 JVM 知識體系。
一、JVM 整體架構圖

二、運行時數據區詳細劃分(JVM 規範 + HotSpot 實現)
1. 程序計數器 — 線程私有
- **作用**:當前線程執行字節碼的行號指示器
- **特點**:
- 唯一**不會 OOM** 的區域
- 執行 Java 方法 → 記錄字節碼地址;執行 Native 方法 → 值為 Undefined
- 線程私有,生命周期與線程一致
2. Java 虛擬機棧 — 線程私有
- **作用**:Java 方法執行的內存模型
- **棧幀結構**:局部變量表、操作數棧、動態鏈接、方法出口
- **異常**:
StackOverflowError:棧深度超限(遞歸過深)
OutOfMemoryError:動態擴展時無法申請記憶體
- **參數**:
-Xss 設定最大棧大小(決定最大遞歸深度)
3. 本地方法棧 — 線程私有
- 服務 Native 方法(C/C++ 實現),功能類似 Java 棧
- HotSpot 將兩者合併實現
4. Java 堆 — 線程共享、最大塊
- **唯一目的**:存放對象實例、數組
- **GC 主戰場**:分代收集 → 新生代 + 老年代
- **細分區域**:
- 新生代:Eden + S0 + S1 (Survivor From/To)
- 老年代:長期存活對象
- **參數**:
-Xmx/-Xms 最大/初始堆,-Xmn 新生代

5. 方法區 — 線程共享
- **存儲**:類信息、常量、靜態變量、JIT 編譯代碼
- **演進歷程**:
| JDK 版本 | 實現名稱 | 參數控制 | 特點 |
| ≤ 1.7 | 永久區 | -XX:PermSize / MaxPermSize | 固定大小,易 OOM |
| 1.8 | 元空間 | -XX:MaxMetaspaceSize | **堆外直接內存**,默認無上限(受限物理內存) |
| 11+ | 元空間優化 | -XX:MaxMetaspaceSize | 類元數據壓縮、CDS 共享 |
6. 運行時常量池 — 方法區一部分
- Class 文件常量池的運行時映射:字面量、符號引用
- **動態性**:
String.intern() 可運行期擴展常量池
7. 直接內存 — 堆外內存
- 非 JVM 規範定義,但頻繁使用(NIO DirectByteBuffer)
- 優點:避免堆↔堆外拷貝、讀寫性能優於堆
- 風險:受限物理內存,可能導致 OOM,難以排查
- 參數:
-XX:MaxDirectMemorySize(默認等於 -Xmx)
三、Java 堆深度剖析與 GC 關聯
分代假設與內存劃分
- **弱分代假設**:絕大多數對象朝生夕死
- **強分代假設**:熬過多次 GC 的對象難以消亡
新生代結構與對象流轉
- 新對象優先分配在 **Eden**
- Minor GC 後存活 → **S0/S1**(雙 Survivor 區輪換)
- 年齡計數器 +1,達到閾值(默認 15) → **晉升老年代**
- 大對象直接進老年代(
-XX:PretenureSizeThreshold)
核心 GC 參數
-Xmx4g -Xms4g -Xmn1.5g
-XX:SurvivorRatio=8 # Eden:S0:S1 = 8:1:1
-XX:MaxTenuringThreshold=15 # 晉升年齡
-XX:+PrintGCDetails -XX:+PrintGCDateStamps
四、Java 虛擬機棧深度實戰
棧幀三大核心組件
| 組件 | 功能 | 關鍵點 |
| 局部變量表 | 存放方法參數、局部變量 | Slot 復用、基本類型/reference/returnAddress、GC Roots 關鍵節點 |
| 操作數棧 | 計算中間結果、臨時存儲 | 字節碼指令操作單元、棧深度影響編譯優化 |
| 幀數據區 | 常量池指針、異常處理表 | 動態連接、異常捕獲分發 |
棧上分配與逃逸分析
- 逃逸分析:判斷對象作用域是否逃出方法/線程
- 標量替換:未逃逸對象拆解為局部變量,直接在棧/寄存器分配
- 同步消除:未逃逸鎖自動移除
- **參數**:
-XX:+DoEscapeAnalysis(JDK 7+ 默認開啟)
五、方法區 / 元空間調優實戰
常見 OOM 場景
- 大量動態生成類(JSP、動態代理、CGLIB、Groovy、JDK 內置代理)
- 大量常量(
String.intern() 濫用)
- 類加載器洩漏(熱部署、OSGi、Tomcat 重啟)
調優參數
# JDK 8+
-XX:MetaspaceSize=256m # 初始觸發 Full GC 閾值
-XX:MaxMetaspaceSize=512m # 最大限制,防止佔盡物理內存
-XX:+UseCompressedClassPointers # 類指針壓縮(默認開啟)
六、JDK 版本關鍵變更速查
| 版本 | 關鍵變更 | 影響 |
| JDK 6 | 永久區、字符串常量池在堆 | PermGen OOM 常見 |
| JDK 7 | 字符串常量池移至堆、永久區符號表優化 | 減少 PermGen 壓力 |
| JDK 8 | **移除永久區 → 元空間**、堆外內存 | 不再受 MaxPermSize 限制,但需監控直接內存 |
| JDK 11+ | ZGC、Shenandoah 低延遲 GC、CDS 應用類共享 | 大堆低延遲、啟動加速 |
七、故障排查工具鏈
- jps / jstat / jinfo / jmap / jstack:JDK 自帶命令行
- VisualVM / JConsole / JMC:圖形化監控分析
- Arthas / Async-profiler:線上診斷、火焰圖
- GC 日誌分析:GCeasy、GCEasy.io、GCViewer
- 上一篇文章: Java 動態代理機制深度解析:InvocationHandler 與 Proxy 核心原理實戰
- 下一篇文章: Java 性能優化權威指南:JVM 吞吐量調優實戰 — CMS 與 Parallel GC 深度解析
Copyright ©
程式碼之家 All Rights Reserved