當我們提到 Java 虛擬機 (JVM) 時,通常指代三個層面的概念:
一個運行中的 JVM 實例有著單一使命:執行 Java 程式。程式啟動時 JVM 啟動,程式結束時 JVM 停止。若在同一台機器上同時運行三個 Java 程式,就會有三個獨立的 JVM 實例並行運作。
JVM 總是從 main() 方法開始執行,該方法必須是 public static void main(String[] args) 簽名。啟動時需指定包含 main 方法的類名。這個初始線程屬於「非守護線程」,而 JVM 內部如垃圾回收等線程則屬於「守護線程」。只要還有任一非守護線程存活,JVM 就不會退出;若有足夠權限,也可通過 System.exit() 強制終止。
JVM 規範定義了子系統、記憶體區域、資料類型與使用指南,構成了嚴格的內部結構與外部行為標準。每個 JVM 實例核心包含:
資料區的具體結構由實現者決定,因此不同 JVM 實現的記憶體佈局差異極大,這使得 JVM 能適應從嵌入式設備到大型伺服器的廣泛平台。
每次方法調用會壓入一個新棧幀,方法結束彈出。棧幀包含三部分:
long/double 佔兩字。JVM 中所有資料皆有嚴格定義的類型,分為基本類型與引用類型。基本類型不依賴對象,直接代表數值;引用類型指向堆上動態創建的對象(或 null)。
基本類型對照表:
| 類型 | 位寬/範圍 |
|---|---|
| byte | 8-bit 有符號補碼 (-2⁷ ~ 2⁷-1) |
| short | 16-bit 有符號補碼 (-2¹⁵ ~ 2¹⁵-1) |
| int | 32-bit 有符號補碼 (-2³¹ ~ 2³¹-1) |
| long | 64-bit 有符號補碼 (-2⁶³ ~ 2⁶³-1) |
| char | 16-bit 無符號 Unicode (0 ~ 2¹⁶-1) |
| float | 32-bit IEEE 754 單精度 |
| double | 64-bit IEEE 754 雙精度 |
| returnValue | 同一方法內 opcode 地址 |
| reference | 堆上對象引用或 null |
註:boolean 在 JVM 內部以 int (0/非0) 或 byte 陣列表示,不存在獨立基本類型。
JVM 最小資料單元為「字」,大小由實現者定義,但必須能容納 int/reference 等,且兩字能容納 long/double。通常至少 31 位,常選擇平台最高效字長。程式運行時無法感知字長,不影響語義。
分為啟動類加載器 (Bootstrap,屬 JVM 實現) 與用戶類加載器 (ClassLoader 子類實例,屬應用程式)。雙親委派模型保證類載入的層級隔離與安全性。類生命週期嚴格遵循:載入 → 連接 (驗證/準備/解析) → 初始化。
存放每個載入類型的完整元資料:全名、父類、修飾符、介面列表、常量池、字段/方法表、靜態變量、類加載器引用、Class 對象引用。常量池是動態連接核心。為提速,非抽象類還會生成方法表,快速定位實例方法。
所有對象/數組分配於堆。規範未強制對象佈局,常見設計有「句柄池+對象池」(便於移動對象、整理碎片) 或「直接指針+偏移量」(訪問快但移動複雜)。每個對象邏輯關聯:鎖 (同步)、wait set (協作)、finalize 執行標記 (GC)。數組是特殊對象,含長度、數據、類型引用;多維數組實為數組的數組。
核心組件,規範定義指令集 (單字節 opcode + 可選操作數) 與執行語義,未限制實現技術。主流技術:解釋執行、即時編譯 (JIT)、熱點編譯、硬體原生執行。基於棧的指令集利於跨平台、網絡傳輸緊湊、驗證安全。
JVM 線程模型映射本地線程以利用多核。優先級 1-10 僅作提示,不保證調度。同步機制包含:對象鎖 (monitor) 與 wait/notify。Java 記憶體模型 (JMM) 定義主內存與工作內存交互規則,volatile/synchronized 保證可見性與有序性。
非強制規範,Sun 標準為 JNI。允許 Java 調用 C/C++ 等本地代碼,擴展功能或複用舊庫。
JVM 以嚴格規範定義行為,以靈活實現適應多平台。理解其架構、記憶體模型、類加載、執行引擎與線程機制,是高效開發、調優與排查 Java 應用的基石。