首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 編譯原理:從原始碼到機器碼、IL、JIT、NGen、ReadyToRun 完整流程

     編輯:關於C#

編譯流程總覽

C# Source (.cs)
    │
    ▼ Roslyn Compiler (csc.exe / CSC.dll)
Intermediate Language (IL) + Metadata → Assembly (.dll/.exe)
    │
    ▼ Runtime (CLR / CoreCLR)
┌─────────────────────────────────────┐
│ JIT Compiler (Just-In-Time)         │
│ 方法首次呼叫 → 編譯為原生機器碼      │
│ 快取於 JIT Code Heap                │
└─────────────────────────────────────┘
    │
    ▼ Execution (CPU)

編譯階段詳細步驟

  1. 語法分析:詞法/語法樹建構
  2. 語義分析:型別檢查、符號解析、多載解析
  3. IL 生成:發出 MSIL 指令、中繼資料表 (TypeDef, MethodDef, MemberRef...)
  4. 組件封裝:PE 格式 (Portable Executable)、CLI Header、Strong Name 簽章

JIT 編譯模式比較

模式觸發時機優點缺點適用場景
標準 JIT方法首次呼叫啟動快、只編譯用到的首次呼叫延遲、重複編譯一般應用
Tiered Compilation分層:快速編譯 → 優化重編譯平衡啟動/極致效能複雜度高.NET Core 3.0+ 預設
ReadyToRun (R2R)建置時預編譯啟動極快、無 JIT 延遲體積大、平台專屬、無 Tiered 優化單檔發布、容器、AOT 需求
NGen / Crossgen安裝/建置時類似 R2R維護困難、版本綁定.NET Framework 時代

IL 指令範例


// C#: int Add(int a, int b) => a + b;
// IL:
.method public hidebysig static int32 Add(int32 a, int32 b) cil managed {
  .maxstack 2
  ldarg.0      // 載入參數 0 (a)
  ldarg.1      // 載入參數 1 (b)
  add          // 整數相加
  ret          // 返回
}

反組譯工具

  • ildasm.exe (SDK 內建) - GUI 瀏覽 IL
  • dotnet-ildasm (Global Tool) - 跨平台
  • ILSpy / dnSpy / dotPeek - 反編譯為 C#、支援去混淆
  • dotnet dump analyze - 記憶體傾印分析

效能優化建議

  • 避免虛擬呼叫熱路徑:sealed、non-virtual、介面約束 where T : struct
  • 內聯友善:小方法、非虛擬、無 try-catch、無複雜控制流
  • [MethodImpl(MethodImplOptions.AggressiveInlining)] 強制內聯
  • [MethodImpl(MethodImplOptions.NoInlining)] 防止內聯 (除錯/追蹤)
  • ReadyToRun 發布:dotnet publish -r win-x64 -p:PublishReadyToRun=true

編譯流程
JIT流程

本文對應《叩響 C# 之門》第 1.4 節編譯教學內容

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved