JVM (Java Virtual Machine) 是 Java「寫一次,到處運行」的基石。理解其內部架構對性能調優、內存排查、故障診斷至關重要。本文系統拆解三大子系統:類加載器、運行時數據區、執行引擎。

負責在運行時動態加載、鏈接、初始化 .class 文件,而非編譯時。
三大內置加載器雙親委派模型:
<JAVA_HOME>/lib 核心庫 (rt.jar 等)<JAVA_HOME>/lib/ext 擴展庫委派規則:子加載器收到請求先委派給父加載器,父無法加載時子才嘗試。打破委派需繼承 ClassLoader 重寫 loadClass()。
執行 <clinit>() 方法:賦值靜態字段、執行靜態代碼塊。觸發條件:new/getstatic/putstatic/invokestatic 字節碼指令、反射調用、主類啟動、子類初始化觸發父類初始化。
線程共享 vs 線程私有:
| 區域 | 共享性 | 核心內容 | OOM 風險 |
|---|---|---|---|
| 方法區 (Metaspace) | 共享 | 類元數據、常量池、靜態變量、JIT 編譯代碼 | Metaspace OOM |
| 堆 | 共享 | 所有對象實例、數組、TLAB | Heap OOM (最常見) |
| 虛擬機棧 | 私有 | 棧幀(局部變量表/操作數棧/動態連接/返回地址) | StackOverflowError |
| 本地方法棧 | 私有 | Native 方法調用狀態 | StackOverflowError |
| 程序計數器 | 私有 | 當前執行字節碼指令地址 | 無 OOM |
returnAddress,Slot 復用優化System.gc() 僅建議,不保證執行native 方法橋接 C/C++ 庫,JNIEnv 指針操作 Java 對象,性能敏感場景或復用舊庫時使用。需注意 JNI 開銷與內存泄漏風險。
-Xms -Xmx -XX:MetaspaceSize 避免擴縮容抖動jstat/jmap/jstack/arthas 監控內存/線程/類加載JVM 不是黑盒,深入掌握其機制是成為資深 Java 工程師的必經之路。