詳細分析 .NET Core 構成體系

來源:互聯網
上載者:User
  前文介紹了.NET Core 在整個.NET 平台所處的地位,以及與.NET Framework的關係(原文連結),本文將詳細介紹.NET Core 架構的構成和各模組主要功能,以及如何?跨平台。

  描述了 .NET Core的系統構成,最上層是應用程式層,是開發基於UI應用的框架組,包括了ASP.NET Core(用於建立web app),和 UWP(用於建立Windows10 app)。

  中介層是公用庫(CoreFX),實現了.NET Standard Library ,囊括了常用系統級操作例如(檔案、網路等)。

  在CoreFx下是運行時環境,.NET Core 包含了兩種運行時(CoreCLR、CoreRT),CoreCLR是一種基於即時編譯器(Just in time compiler,JIT)的運行時,它使用了跨平台開源的編譯器RyuJIT,而CoreRT是使用提前編譯器(Ahead of time compiler,AOT)的運行時,它既可以使用RyuJIT來實現AOT編譯也可以使用其他的AOT編譯器。由於AOT提前編譯IL成了機器碼,在行動裝置上也具有更好的啟動速度和節能性。

  最後還要提到一個開源的跨平台原始碼編譯器Roslyn,它有別於剛才兩個編譯器,JIT和AOT編譯器主要用於將IL編譯成本機機器碼,而Roslyn是將C# 或 VB.NET 代碼編譯成程式中繼語言(intermediate language,IL)。

 Roslyn 編譯器

  Roslyn編譯器用於將C#或VB.NET代碼編譯為程式集(assembly),它的編譯過程是一個管道式的處理過程一共包含4個步驟,具體過程見。

  A. Parser(解析)

  根據文法對原始碼進行解析。

  B. Declaration (聲明)

  為代碼產生中繼資料(metadata),中繼資料是一個資料表的集合,描述了在當前代碼中定義的資料類型和成員,同時也描述了引用的類型及成員。

  C. Bind(綁定)

  將產生的IL代碼與描述它的中繼資料綁定在一起,產生託管模組(managed module)。

  D. Emit(產生)

  將一個或多個託管模組合并產生程式集(assembly)。

 RyuJIT 編譯器

  在程式運行中需要執行某一個方法,首先需要將已經編譯好的IL轉換原生機器碼,而這個任務就交給了RyuJIT。它是新一代JIT編譯器,第一次實現了AMD64的架構,RyuJIT能夠比JIT64(上一代編譯器)更快地產生代碼,以提高程式運行效率。

 CoreCLR & CoreRT

  .NET Core Runtime (CoreCLR) 和 .NET Core Runtime (CoreRT) 都是.NET Core的運行時(Runtime),它們提供了與.NET Framework CLR 類似的核心功能(記憶體管理、程式集載入、安全性、異常、線程管理等),可由面向於運行時的所有語言使用。

  CoreRT 和 CoreCLR 不同的是,CoreRT 提供了一套AOT 的機制,可以將.NET Core程式編譯成原生代碼,不依賴 .NET 運行時而運行在宿主機器上。除此之外兩個運行時大部分功能代碼是共用的,比如GC。AOT的最佳化帶來不少好處:

  • 編譯後產生一個單檔案,包含所有的依賴,包括 CoreRT,無需安裝Framework

  • 啟動時是機器碼,不需要產生機器碼,也不要載入JIT編譯器

  • 可以使用其他最佳化編譯器,包括 LLILC ,IL to CPP

  CoreRT有兩個方式產生機器碼,第一個使用是直接編譯IL成機器碼,預設情況下,RyuJIT 作為一個 AOT 編譯器將IL編譯成機器碼,另一個方式是將C#代碼編譯成C++代碼,然後調用對應平台的C++編譯器最佳化編譯成機器碼。

  使用 RyuJIT 編譯成機器碼

dotnet restoredotnet build --native --ilcpath <repo_root>\bin\Product\Windows_NT.x64.Debug\packaging\publish1

  編譯產生 C++ 代碼

dotnet restoredotnet build --native --cpp --ilcpath <repo_root>\bin\Product\Windows_NT.x64.Debug\packaging\publish1 --cppcompilerflags /MTd

  CoreRT也有不足之處,它需要為不同平台編譯一次;但凡事有但是,它允許工程師可以不發布到不想支援的平台(比如某遊戲僅支援案頭,不支援手機)。

註:這兩個命名在.NET Core RC2 版本中均無法使用,按照官方說法是在目前的版本中已經移除這個命令了,具體等6月27日正式版發出後才知道最後的情況

 CoreFX(.NET Core Libraries)

  CoreFX主要包含數個公用庫,例如 System.Collections, System.IO, System.Xml等。CoreFX是 .NET Standard Library 的實現,同樣的.NET Framework 4.6.3也是基於.NET Standard Library的實現。它們目前都是基於.NET Standard Library1.6版本,具體見下表:

 .NET Core 代碼開發、部署、運行過程

  從可以看到使用JIT編譯和使用AOT編譯原始碼並運行程式是兩種不同的流程。

  如果使用JIT編譯器部署程式時只需要將程式打包為IL的assemblies,在方法第一次執行前編譯器將IL編譯為目標機機器碼(Native code),而AOT編譯會在編譯時間將原始碼直接編譯為目標機機器碼。

  AOT將原始碼編譯為機器碼,擁有如下特性:

  • 用靜態代碼替換反射,例如如果一個實值型別(value type)沒有重寫 ValueType.Equals 的equals的方法,預設情況判斷相等,會使用反射找到filedinfo以確定type是否相等,然後再比較value是否相等。而在AOT編譯中由於替換了反射因此只能比較value是否相等。

  • 依賴的第三方類庫以及.NET Libraries均打包至最終編譯的程式中。

  • 打包後的程式運行在一個精簡版的運行時上(CoreRT)主要包含記憶體回收行程,而運行時也會打包在app檔案中。

  • 雖然編譯時間會替換反射代碼,但遇動態反射代碼無能為力,運行時若遇動態反射調用則會因找不到對應的中繼資料及實現而拋出異常。解決辦法是編譯前配置運行時指令檔案(Runtime directive file)指定需要用到的程式集。

 總結

  本節介紹了.NET Core的構成體系,包括新增的多個編譯器以及遵循.NET Standard Library的CoreFX,總體來說.NET Core較之前的.NET Framework 從效能和開發效率上都有很大的提升。關鍵是首次實現了.NET的完全跨平台能力的基礎技術棧。

  .NET Core 基於跨平台能力,並沒有將與 GUI 高度相關的 API 移植到 .NET Core 內,因此像是 Windows Forms 或是 Windows Presentation Foundation (WPF) 並未移植到 .NET Core。.NET Core 支援控制台應用程式 (Console Application) 以及類庫 (Class Library) 類型的項目。

  不過微軟在其 Universal Windows Platform (UWP) 開發平台使用了 .NET Core,並且利用 .NET Native 技術將其效能提升至十分接近原生碼的速度。

  ASP.NET Core 則以控制台應用程式驅動其託管環境 Kestrel Server 以支援 ASP.NET Core 程式的運行。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.