Java 引入虛擬機(JVM)作為抽象計算機層,屏蔽底層硬件與作業系統差異。編譯器(javac)生成字節碼——面向 JVM 的中間指令集,而非特定 CPU 的機器碼。各平台 JVM 負責將字節碼解釋執行或即時編譯(JIT)為本地機器碼,實現「一次編寫,到處運行」。
採用雙親委派模型:
流程:加載 → 驗證 → 準備 → 解析 → 初始化 → 使用 → 卸載。初始化階段執行 <clinit>(靜態塊/靜態字段賦值),由 JVM 保證多線程安全。
| 區域 | 線程私有/共享 | 核心職能 | OOM 風險點 |
|---|---|---|---|
| 程序計數器 (PC Register) | 私有 | 當前執行字節碼行號 | 極少 |
| 虛擬機棧 (JVM Stack) | 私有 | 棧幀:局部變量表、操作數棧、動態鏈接、方法出口 | StackOverflowError(遞歸過深) |
| 本地方法棧 | 私有 | 服務 Native 方法調用 | StackOverflowError |
| 堆 | 共享 | 對象實例、數組分配主戰場,GC 主戰場 | OutOfMemoryError: Java heap space |
| 方法區 (Metaspace) | 共享 | 類元數據、常量、靜態變量、JIT 編譯代碼緩存 | OutOfMemoryError: Metaspace |
| 直接內存 | 共享 | NIO DirectByteBuffer、JNI 分配,不受堆限制 | OutOfMemoryError: Direct buffer memory |
堆劃分為新生代 (Eden + S0 + S1)與老年代,對象優先在 Eden 分配,大對象直接進老年代,長期存活對象晉升老年代。
| 收集器 | 代 | 算法 | 特點 | 適用場景 |
|---|---|---|---|---|
| Serial | 新/老 | 複製/標記-整理 | 單線程、停頓長 | Client 模式、單核 |
| Parallel Scavenge | 新 | 複製 | 多線程、吞吐量優先 | 批處理、科學計算 |
| ParNew | 新 | 複製 | Serial 多線程版,配合 CMS | 舊版 Server 模式 |
| CMS | 老 | 標記-清除 | 並發標記/清除、停頓短、碎片化 | 響應敏感應用(已废弃) |
| G1 | 全堆 | 標記-整理+複製 | Region 劃分、可預測停頓、混合收集 | JDK 9+ 默認、大堆低延遲 |
| ZGC / Shenandoah | 全堆 | 並發整理 | 亞毫秒停頓、彩色指針/連接矩陣 | 超大堆 (TB 級)、極致低延遲 |
Class 文件採用類 C 結構體:魔數、版本、常量池、訪問標誌、類/父類索引、接口表、字段表、方法表、屬性表。
字節碼指令分類:載入/存儲 (aload, istore)、運算 (iadd, fmul)、類型轉換 (i2l)、對象創建/訪問 (new, getfield)、棧操作 (dup, swap)、控制轉移 (ifeq, goto)、方法調用 (invokevirtual, invokedynamic)、異常處理 (athrow)、同步 (monitorenter)。
JVM 是 Java 生態的基石。深入理解類加載機制、內存分代模型、GC 演算法權衡、JIT 編譯優化,能幫助開發者:
隨著 GraalVM、CRaC (協調還原檢查點)、Project Leyden 等前沿技術演進,JVM 正向即時啟動、極致吞吐、原生镜像方向邁進,持續重新定義 Java 的性能邊界。