C#/.NET CLR:公共語言執行時

2020-07-16 10:04:46
CLR 是 .NET 平台的核心,沒有之一。

元件物件模型(Component Object Mode, COM)是 CLR 的前身,它將 Windows 平台上執行的所有成員標準化,並定義了它們之間溝通的規範,使得不同程式語言的進程間通訊和動態物件建立成為可能。

所有 COM 元件都實現了 IUnknown 介面,採用參照計數管理物件的生命週期。

當微軟開始 .NET 框架的開發時,他們最終決定改進現有的 COM,並將它命名為公共語言執行時(Common Language Runtime, CLR)。

CLR 中元件間的溝通規範由後設資料 (metadata)負責,因此,每個可遷移執行檔案(即 .exe 檔案)都包含了後設資料,以便 CLR 知道檔案內部的型別是什麼。

所以,有人稱“CLR 是一個更好的 COM”。

CLR 是讓 .NET 程式執行所需的外部服務的集合,.NET 平台的核心和最重要的元件,類似於 Java 的 JVM。

它有如下的核心功能:
  • 在程式的第一步編譯時,將程式通過對應的編譯器編譯為 IL,並生成後設資料。將 IL 和後設資料打包,加入 PE 和 CLR 檔案頭使之成為託管模組,將各個模組打包為程式集(不過,語言編譯器不被看作 CLR 的一部分)。
  • 程式執行時,型別檢查器負責保證型別安全(程式碼驗證),即時編譯器(JIT)負責將 IL 編譯為機器碼。
  • 型別載入器(Class loader)負責通過清單和後設資料探測型別的位置,並載入需要的型別,生成型別物件,包括方法表等。
  • 方法呼叫。
  • 自動記憶體管理和垃圾回收(COM 使用參照計數,而 CLR 使用標記清除)。
  • 執行緒池管理。
  • 字串駐留池管理。
  • 例外處理。
  • 動態載入程式集(晚期系結),這是和型別載入器互動的必然結果。
  • 與 COM 元件的互動。

可以看到,絕大部分功能都是在程式執行時保證程式的順利執行的。

因此,CLR 管理 .NET 程式集的執行,執行於作業系統之上。

CLR 的一些功能僅僅是作業系統的一個再包裝,例如執行緒,記憶體管理等,這些實際上是進一步呼叫作業系統 API,存取核心物件。

但 JIT 則是它獨有的,如果沒有它,就不能把 IL 變成機器碼,計算機也就不認識 C#,你也就不能執行 C# 程式。

對 CLR 了解越多,對整個 .NET 的把握就越好。

受控代碼是必須在 CLR 下執行的程式碼,而非受控代碼則不需要 CLR 的支援就可以執行。

CLR 本身用於管理受控代碼,因此它是由非受控代碼編寫的,而並不是一個包含了受控代碼的程式集,也不能使用基於 IL 的反編譯工具進行檢視。

CLR 位於 C:%SystemRoot%Microsoft.NETFramework[ 版本號 ]下,對應不同的機器有兩個版本,一個是工作站版本的 mscorwks.dll,一個是伺服器版本的 mscorsvr.dll。

wks 和 svr 分別代表 workstation(工作站) 和 server(伺服器)。