.NET6 平台系列3 .NET CLR 詳解
- 2021 年 4 月 26 日
- 筆記
- .NET Framework, .NET、.NET Framework, .NET6
運行時(Runtime Environment,簡稱Runtime ),是指那些支援在特定的平台上,用於運行特定程式語言編寫的軟體的庫和程式集,它一般要處理軟體和作業系統之間的介面細節。例如,系統調用、程式的啟動和終止、記憶體管理等。 運行時分3種:純靜態環境(如Fortran)、基於堆棧環境(如C、C++、Pascal)、純動態環境(如SmallTak、Java)。
CLR(Common Language Runtime),處於 .NET Framework 的最底層,它是 .NET Framework 的核心。CLR 是一個軟體引擎,提供載入應用程式、程式編譯、錯誤檢查、安全許可認證、執行緒管理、遠程處理、執行、清空記憶體等核心服務。 CLR 是屬於純動態運行時的一種,它的主要組成部分是虛擬執行引擎 VEE(Vitual Execution Enging)。
使用 ASP.NET Web Form 開發的應用程式,部署到IIS伺服器時,不同的CLR版本需要選擇不同的託管管道模式。
CLR主要由以下11個功能器件組成。
(1)類載入器(Class Loader):將應用程式的彙編載入到記憶體中。彙編包括微軟中間語言(Microsoft Intermediate Language,簡稱MSIL)程式碼、描述應用程式中組件的元數據(類和類的布局描述),以及其他應用程式所需的組件。
(2)即時編譯器(Just-In-Time,簡稱JIT):負責將MSIL翻譯成本機執行程式碼。
(3)程式碼管理器(Code Manager):管理程式碼的執行。
(4)垃圾回收器(Garbage Collection):負責整個.NET運行時託管程式碼的記憶體分配與釋放任務,它通過一定的優化演算法選擇收集對象和時間,並進行自動的垃圾收集。
(5)安全引擎(Security Engine):提供基於認證的安全機制,如用戶身份。
(6)調試引擎(Debugger):使開發者能調試和跟蹤應用程式程式碼。
(7)類型檢查器(Type Checker):檢查並禁止非安全的類型轉換以及未初始化的變數的使用。
(8)異常管理器(Exception Manager):提供結構化的異常處理,與Windows結構化異常處理機制(SHE)集成,改進了錯誤報告。
(9)執行緒支援(Thread Support):提供了多執行緒編程的類和介面。
(10)COM列集器(COM Marshaler):處理與COM之間的配置。
(11).NET 基礎類庫(BCL):集成具有支援.NET Framework 類庫運行時的程式碼。
編譯器(Windows平台上有3個不同的JIT編譯器)
1、JIT — 標準編譯器。運行時默認使用的JIT編譯器。程式碼高度優化,資源開銷大,它要求電腦具有足夠的記憶體來高速快取編譯後的程式碼,以便重複利用。如果沒有足夠的記憶體來高速快取編譯後程式碼,就需要反覆調用JIT,由於優化技術需要花時間,這樣就大大降低了編譯的速度。
2、EconoJIT — 經濟編譯器。它不是執行優化技術的編譯器。程式碼不能高速快取,但可以把MSIL快速轉換成託管的原始程式碼,編譯速度快。
3、PreJIT — 類似傳統的編譯器。實現將應用程式首次安裝到電腦時,就把整個應用程式轉換為本機程式碼。
編譯過程
(1)編譯器首先將各類.NET 上支援的語言(C#、VB.NET、VC++等)編寫的源程式碼編譯託管的中間語言(MSIL)程式碼,不是機器碼。這個MSIL就構成可移植執行的 .exe文件(Portable Executable,檢查PE)。在編譯器將源程式碼編譯成MSIL的同時,元數據引擎也產生元數據資訊,這些程式碼也可和其他語言編譯的程式碼鏈接為一個EXE或DLL文件(通過鏈接器實現)。
(2)由於本地的CPU不能直接執行MSIL指令。當執行應用程式時,首先類載入器將應用程式的彙編(MSIL程式碼和元數據)載入到記憶體中,然後使用其中的元數據載入任何應用程式所需要的組件支援的彙編並進行類型安全和版本檢查。例如:它可能載入一個桌面應用程式所需要的圖形用戶介面(GUI)控制的彙編等。
(3)CLR 並不是將應用程式的所有MSIL的程式碼都翻譯成CPU指令程式碼,僅當用戶需要運行一個託管的應用程式時,作業系統裝載器才載入 CLR,這時CLR 才開始翻譯該應用的MSIL程式碼。當然,如果開發人員希望在應用程式首次安裝到電腦中時就全部從MSIL轉變為本機程式碼,那麼可以使用 PreJIT 編譯器實現,PreJIT自動把MSIL轉換本機程式碼。
(4)JIT編譯器和其他大多數編譯器是不用的。JIT編譯器只執行編譯這個過程,而在其他編譯器(C和C++)中要經過編譯和鏈接兩個階段。也就是說,.NET下的源程式(C#等)並不被編譯成目標文件(.obj),而是直接生成可執行文件(.exe)或動態鏈接庫(.dll)。在.NET下,編譯器不需要包含鏈接器。
技術棧
1、.NET:C#、.NET5、.NET6、.NET Core、MVC、ASP.NET Core、Web API、RESTful API
2、jQuery、Vue.js、Bootstrap
3、資料庫:SQLServer、MySQL、PostgreSQL、Oracle、SQLite、SequoiaDB 、
Redis、MongoDB、ElasticSearch、TiDB
4、ORM:Dapper、Entity Framework、FreeSql、SqlSugar、分庫分表
5、架構:領域驅動設計 DDD、ABP
6、環境:跨平台、Linux、Windows、MaxOS、IIS、Nginx
7、移動App:Android、IOS、HarmonyOS、微信、小程式、快應用、
Xamarin、uni-app、MUI、Flutter、Framework7、Cordova、Ionic、React Native、Taro、NutUI、
mpvue、Smobiler
其他:
- 雲原生、CI/CD、DevOps、微服務、Docker、K8S
- Dapr、RabbitMQ、Kafka、分散式、大數據、高並發、負載均衡、中間件
- RPC、ELK
- .NET + Docker + jenkins + Github + Harbor + K8S
- Python、Go