一、JVM 生命週期
- 啟動:由
main() 方法(public static void main(String[]))啟動,主執行緒為非守護執行緒
- 運行:只要有非守護執行緒存活,JVM 就不會退出
- 關閉:正常關閉(最後一個非守護執行緒結束)、
System.exit()、OS 信號(SIGTERM)、JNI DestroyJavaVM
- 守護執行緒:GC、JIT 編譯、RMI 等內部服務執行緒,不阻止 JVM 退出
二、Java 代碼編譯與執行全流程
.java 源碼
↓ javac (前端編譯器:詞法/語法/語義分析 → 字節碼生成)
.class 字節碼
↓ 類載入器子系統 (載入 → 驗證 → 準備 → 解析 → 初始化)
方法區/堆 中的運行時資料結構
↓ 執行引擎
├─ 解釋器 (逐條執行字節碼)
└─ JIT 編譯器 (C1 Client / C2 Server / Graal) → 機器碼直接執行
1. 前端編譯
- 輸入:
.java → 詞法分析 → 語法樹 (AST) → 語義分析(符號表、類型檢查、註解處理) → 字節碼生成
- 輸出:
.class 包含結構資訊、元數據(常量池、類/方法/欄位簽名)、方法資訊(字節碼、異常表、行號表、局部變量表)
2. 類載入機制
雙親委派模型
Bootstrap ClassLoader (C++ 實現) → rt.jar 核心類庫
↑
Extension ClassLoader → jre/lib/ext/*.jar
↑
Application ClassLoader (AppClassLoader) → classpath
↑
Custom ClassLoader (Tomcat/WebLogic/OSGi 等)
- 檢查已載入:自底向上(Custom → Bootstrap)
- 實際載入:自頂向下(Bootstrap → Custom)
- 保譼同一類只被載入一次(同一類載入器命名空間)
載入三步驟
- 透過全限定名獲取二進制字節流
- 將靜態結構轉為方法區運行時資料結構
- 在堆中生成
java.lang.Class 實例作為訪問入口
3. 執行引擎與棧幀結構
JVM 基於棧架構,每個執行緒私有:
- 程序計數器 (PC):當前執行字節碼偏移量
- Java 虛擬機棧:棧幀鏈,每個方法調用對應一幀
- 本地方法棧:Native 方法服務
棧幀組成
| 區域 | 功能 |
| 局部變量表 | 方法參數、局部變量、this 引用(Slot 為單位,long/double 佔 2 Slot) |
| 操作數棧 | 字節碼指令運算中間結果(入棧/出棧) |
| 動態連接 | 指向運行時常量池該方法引用,支援動態調用 |
| 方法返回地址 | 正常/異常返回位置 |
4. JIT 即時編譯優化
- 分層編譯:C1 (Client, 快速啟動) → C2 (Server, 激進優化) → Graal (實驗性)
- 熱點探測:方法計數器 + 回邊計數器,達閾值觸發編譯
- 核心優化:方法內聯、逃逸分析、標量替換、鎖消除、空值檢查消除、分支預測
- 去優化:假設失效(如類載入導致繼承關係變化)回退至解釋執行
三、關鍵參數速查
-Xms/Xmx 堆初始/最大值
-Xmn 新生代大小
-XX:MetaspaceSize 元空間初始值
-XX:+UseG1GC 啟用 G1 收集器
-XX:+PrintCompilation 輸出 JIT 編譯日誌
-XX:CompileThreshold=10000 觸發編譯調用次數
- 上一篇文章: JDK 安裝與環境配置全平台指南(Windows / Linux / macOS)
- 下一篇文章: Maven 3.3.9 安裝與環境配置完整指南(Windows/Linux)
Copyright ©
程式碼之家 All Rights Reserved