[.NET大牛之路 005] .NET 的執行模型

.NET大牛之路 • 王亮@精緻碼農 • 2021.07.06

目錄:

前面我們介紹 .NET 歷史時講過,微軟基於 .NET Framework 重新設計並創造了跨平臺的 .NET Core,目前已經發展到 .NET 5 版本,它的性能較之前的 .NET Framework 有巨大的提升。而 .NET Framework 產品線也被宣告終止(微軟仍會繼續維護,只是不會再發布新版本),它的最後個版本 .NET Framework 4.8 成爲了絕唱。

.NET Framework 終將成爲歷史,我們要把思想從 .NET Framework 跳到 .NET Core/.NET 5+,首先要弄明白它們的執行模型和底層架構發生了什麼變化。

注:爲了簡單起見,下文所說的 .NET Core 包含 .NET Core 和 .NET 5+。

我們先從一個高的角度來理解一下 .NET Core 執行模型的全貌,後面章節再從低的角度逐個拆開講解各個模塊。

.NET Core 的執行模型有兩種,一種是基於 CoreCLR 運行時,這種和 .NET Framework 的執行模型幾乎一樣;另一種是基於 Native AOT 本地運行時,這是 .NET Core 新增的一種執行模型。

基於 CoreCLR

CoreCLR 和原來 .NET Framework 的 CLR(Common Language Runtime,公共語言運行時)幾乎是一樣的,只是 CoreCLR 去除了特定於 Windows 操作系統的部分,實現了跨平臺。所以除了 CLR 運行時有些不同之外,它們的執行模型是一樣的。

注意,平時我們會把 CoreCLR 習慣性地簡稱爲 CLR,在 .NET Core 語境中,CLR 指的就是 CoreCLR。

基於 CoreCLR 的執行模型用簡單流程圖表示如下:

源代碼經過編譯器編譯,生成程序集,運行的時候,再由 CLR 針對不同的操作系統和 CUP 架構(如 x86、x64 或 ARM)把程序集編譯成本地代碼(Native Code),本地代碼可由操作系統直接運行。

注:在 .NET 中,本地代碼就是機器碼(Machine Code),只是叫法不同。它是處理器能夠理解並直接執行的字節碼指令。所有其他代碼必須翻譯或轉換爲機器碼才能在計算機上運行。

基於 Native AOT

.NET Core 基於 CoreCLR 提煉出了一個精簡版的本地運行時,移除了 JIT 編譯器,保留了垃圾回收器、內存管理等模塊。這個本地運行時之前的代號叫 CoreRT ,現在叫 Native AOT

Native AOT 運行時提供了一套 AOT(Ahead Of Time) 提前編譯機制,它使用的是新一代的 RyuJIT 編譯器,可以將 .NET Core 程序編譯成本地代碼(機器碼),可在宿主機器直接運行,不需要提前安裝 .NET Core 運行時。

基於 Native AOT 運行時的執行模型用簡單流程圖表示如下:

源代碼經過編譯器編譯,直接生成本地代碼,發佈時將本地代碼和本地運行時一起打包爲單個可執行文件,可直接在操作系統上運行。

要使用本地運行時,在 VS 中發佈時請選擇 Self-Contained 模式,同時需指定目標平臺及 CPU 架構(如win-x64linux-x65等)。由於打包的文件包含本地運行時,所以它要比基於 CoreCLR 發佈的文件要大幾十兆。

使用 Native AOT 本地運行時有兩大好處:一是發佈時只有一個文件,已經包含本地運行時,不需要提前安裝運行時環境,可直接在宿主機上運行;二是啓動時本身就是機器嗎,不要經過 JIT 編譯器編譯,啓動效率更高。

小結

.NET Core 基於 CoreCLR 的執行模型和原來 .NET Framework 的執行模型是一樣的,沒有發生大的變化。另外,.NET Core 新增了一種基於 Native AOT 本地運行時的執行模型,它使用了 AOT 編譯機制,可直接把 .NET Core 程序編譯成機器碼。

希望大家根據文中的流程圖理解 .NET Core 兩個執行模型的全貌,並牢記。這有助於我們理解 .NET 程序的運行原理,也是面試的高頻話題。關於執行模型中的主要核心模塊(編譯器、程序集和運行時),後面的章節再單獨詳細講解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章