OpenJDK HotSpot JVM 由執行引擎(垃圾回收器、即時編譯器)和運行時(類加載、字節碼驗證、解釋器)組成。本文聚焦 JIT 編譯器,特別是 JDK 8 默認的分層編譯架構及其優化技術。
-XX:+PrintCompilation 等)HotSpot 包含兩類編譯器:
JDK 8 默認啟用 分層編譯,結合 C1 和 C2 優勢。可通過 -XX:-TieredCompilation 禁用,退回純 C2 模式。
| 層次 | 名稱 | 特點 |
|---|---|---|
| 0 | 解釋執行 | 收集性能分析數據,識別熱點方法 |
| 1 | 簡單 C1 編譯 | 無性能分析信息,快速編譯 |
| 2 | 受限 C1 編譯 | 少量方法編譯,收集調用次數、循環分支信息 |
| 3 | 完整 C1 編譯 | 所有 C1 編譯方法及完整性能分析信息 |
| 4 | C2 編譯 | 服務端編譯器,最高優化級別 |
分層編譯通過低層次快速編譯改善啟動性能,高層次利用收集的性能分析信息生成高度優化代碼。
-XX:ReservedCodeCacheSize 增大。-XX:Tier3MinInvocationThreshold),第三層最低調用閾值 100,遠低於非分層 C1 的 1500,導致編譯更頻繁。輸出格式:timestamp compilation-id flags tiered-level class::method @osr_bci code-size [deoptimization]
567 693 % ! 3 org.h2.command.dml.Insert::insertRows @ 76 (513 bytes)
656 797 n 0 java.lang.Object::clone (native)
779 835 s 4 java.lang.StringBuffer::append (13 bytes)
%:OSR (On-Stack Replacement) 方法!:有異常處理器s:同步方法n:原生方法類加載導致優化假設失效時,JVM 執行去優化:方法從高層退回低層或標記為 "not entrant"/"zombie" 待回收。PrintCompilation 會輸出 made not entrant、made zombie 等標記。
將調用替換為方法體,消除調用開銷。-XX:+PrintInlining 可查看決策:
@ 80 java.io.BufferedInputStream::getBufIfOpen (21 bytes) inline (hot)
@ 91 java.lang.System::arraycopy (0 bytes) (intrinsic)
@ 76 java.util.zip.Inflater::setInput (74 bytes) too big
受方法大小、調用熱度限制。intrinsic 表示內部函數(手工優化的特殊方法,如 System.arraycopy)。
利用 SIMD 指令並行處理數據。HotSpot 提供兩級支持:
a[j] = b + c * z[i] // 展開後可自動向量化
判斷對象是否逃逸出方法/線程。未逃逸對象可:
HotSpot 分層編譯通過多層次協作,在啟動速度與峰值性能間取得平衡。理解編譯層次、代碼緩存、診斷開關及核心優化(內聯、向量化、逃逸分析),有助於深度調優 JVM 性能。