本節聚焦 .NET 在程式碼最終轉為機器碼三種模式:JIT Just-In-Time、R2R ReadyToRun、Native AOT Ahead-Of-Time。它們共享同一套 IL 中間語言輸入與執行時元件,但在轉換時間點、佈署產物形態、啟動特徵、可反射性與平臺可攜性上顯著不同。為了避免僅流於概念,後段會以實際專案與 PowerShell 測量展示差異。
核心觀點先行:JIT 是延遲策略,換取最高動態最佳化與平台適配;R2R 是在 IL 與 Native 之間插入「預先部分編譯」層,降低第一次 JIT 時間但保留 JIT 彈性;Native AOT 則是盡可能完全在編譯階段產生靜態機器碼並移除不必要執行時元件,換來啟動與記憶體常駐最小化,代價是反射與動態特性需顯式保留、跨平台需交叉編譯、編譯時間與工具鏈需求較高。
名詞界定:JIT 指 CLR CoreCLR 內部的 tiered compilation 過程:方法首次執行時 Tier 0 快速編譯產生 baseline 機器碼,熱點方法再升級至 Tier 1 包含 PGO Profile-Guided Optimization 的優化;R2R 產物內嵌經 crossgen2 預編的本機碼與 IL 雙份,執行期可直接載入預編碼或視需要 fallback JIT;Native AOT 則使用 ahead-of-time toolchain 將 IL、必要 BCL 成員與 metadata trimming 後生成單一或少量平台原生檔案(Windows exe + .dll; Linux ELF),不再需要 JIT 子系統。IL 在 Native AOT 中多數不再保留原樣,metadata 也被壓縮裁剪,造成反射模型受限。
啟動行為比較:JIT 首次啟動需載入 CLR、JIT 編譯若干必要方法例如 Main、靜態建構式、初期呼叫鏈,大量小型 CLI 工具會受益於降低 JIT 數量例如 trimming 或 R2R;R2R 啟動時會直接映射預編 native section 減少前幾百個方法 JIT 延遲,典型啟動改善 10%~40% 取決於 I/O 與方法數;Native AOT 啟動則近似原生 C 程式:OS 載入器直接建立進程、執行 runtime 啟動 stub 後跳入 Main,啟動延遲主要來自檔案 I/O 與記憶體配置,極小工具可達數毫秒級,較 R2R 再下降顯著 GC Heap 初始大小也較小。