CLR(公共語言運行時)

来源:https://www.cnblogs.com/green-jcx/archive/2022/04/13/16140157.html
-Advertisement-
Play Games

從編程開發的角度來簡單來說,CLR就相當於“執行/運行”我們所編寫程式的“環境/服務”。這就好比如我們組裝了一個賽車,我們的賽車需要依賴“跑道”作為一個環境,賽車才能進行飛馳。而這個“跑道”就類似於CLR。在Java平臺中程式員要向一臺電腦部署軟體時,要確保軟體運行,電腦上就要按照JVM(Java虛 ...


從編程開發的角度來簡單來說,CLR就相當於“執行/運行”我們所編寫程式的“環境/服務”。這就好比如我們組裝了一個賽車,我們的賽車需要依賴“跑道”作為一個環境,賽車才能進行飛馳。而這個“跑道”就類似於CLR。在Java平臺中程式員要向一臺電腦部署軟體時,要確保軟體運行,電腦上就要按照JVM(Java虛擬機),那麼這裡的“Java虛擬機”就相當於我們.NET平臺的CLR(Common Language Runtime,公共語言運行時)。

 

對CLR整體概況來說,CLR是一個軟體層面的代理服務,它負責管理.NET程式集的執行/運行,其中主要包括:

  • 管理應用程式域
  • 載入和運行程式集
  • 安全檢查
  • 線程管理
  • 將CIL代碼即時編譯為機器代碼
  • 異常處理機制
  • 對象析構
  • 垃圾回收

註意,這些執行項目並非發生在編譯時,而是發生在程式運行的過程中,也因此名稱中包含了“運行時”一說。

 

CLR是.NET框架中最核心的部分,從上述的講解中我們只能對CLR有個簡單的印象,通過幾句話或者某些概念也並非能夠對CLR有一個深刻的理解,如果你想要牢記它,就必須知道它的作用以及它的工作流程,接下來開始隨著本文開始更進一步的學習。


1.讀取程式集

CLR在對CIL語言代碼進行編譯前,需要先將編譯的環境運行起來並對程式集進行一個讀取過程,這個讀取過程其實也就描述出了程式集中的一個基本構造。

讀取過程如下:

1.1.文件格式

操作系統首先檢查文件是否是一個可執行文件,對於Windows操作系統而言可執行文件就是:“PE/COFF(windows可移植可執行/通用對象文件格式)”。在檢查完文件是否是可執行文件後,操作系統會在檢查文件格式中是否包含“CLR頭”,如果存在“CLR頭”,那麼操作系統就知道該文件是一個.NET程式集,需要區別於其他類型的可執行程式。

1.2.清單

在讀取到“CLR頭”確認文件是一個程式集之後,會讀取程式集中包含的清單(manifest)。這個清單相當於一個目錄,描述了程式集自身的基本信息。這其中包括:程式集的標識(名稱和版本)、描述構成程式集的所有文件、程式集所有外部依賴項的列表等。

1.3.元數據

清單之後就是元數據,在.NET中查看元數據的過程也叫做反射。如果說清單描述了程式集自身的信息,那麼元數據則描述了程式集包含了哪些內容項。這些內容項包括:程式集包含的模塊、類型、類型的成員、類型和類型成員的可見性等。另外要強調的是,元數據並不包含其中內容項的具體實現。

1.4.CIL和資源

在接下來就是:已經被編譯器轉換的CIL代碼和一個資源文件。CIL代碼也就是元數據中所有類型的具體實現,例如包括:方法體、欄位等。資源文件代表程式集所嵌套包含的文件,其中會包含一些如:jpg、xml、txt等文件。


2.非托管的CLR

托管代碼之所以被稱為托管代碼,是因為它是由CLR進行托管的,所以間接的可以猜測到CLR肯定不是托管代碼編寫的。這就是好比如警察負責捉小偷,總不能找個小偷去捉小偷吧。因為CLR本身是用於管理托管代碼的,因此它是由非托管代碼C++編寫的。另外我們可以通過命令行工具在本機上查看對應CLR運行時的版本,如圖:


3.CLR運行工作流程

操作系統首先會檢查程式集文件中是否包含PE頭和CLR頭,如果存在則會載入mscoree.dll組件,mscoree.dll是CLR中最重要的一個組件,又稱公共對象運行庫執行引擎。它在載入之後,會調用它其中的_CorExeMain函數,該函數會根據程式集而載入合適版本的CLR。

 

在CLR運行之後,程式的執行權就叫給了CLR。CLR會找到程式入口點,通常是Main()方法,然後執行它。這個執行過程包含以下內容:

 

3.1.載入類型 Class loader(類載入程式)

在執行“程式入口點”之前,CLR首先要找到“程式入口點”的所在的類型並且載入這個類型。

CLR中一個名為Class loader(類載入程式)的組件負責這項工作。它會從GAC、配置文件、程式集元數據中尋找這個類型,然後將它的類型信息載入到記憶體中。在Class loader找到並載入完這個類型之後,它的類型信息會被緩存起來,這樣就無需再次進行相同的過程。在載入這個類以後,還會為它的每個函數插入一個存根。

另外,在類型載入是時候,CLR不光會載入我們自定義的程式集,這其中還會與.NET的基礎類庫中的類型進行交互。也就是對mscorlib.dll這個程式集進行類型載入,這個程式集封裝了各種我們常用的編程類庫和核心的數據類型。

 

3.2.驗證

在CLR中,還存在一個驗證程式(verfier),該驗證程式的工作是運行時確保代碼是類型安全的。註意驗證兩個方面,一個是元數據是否正確,另一個是CIL代碼必須是類型安全的,類型的簽名必須正確。例如,代碼不允許以允許記憶體位置溢出的方式訪問對象的欄位、驗證檢查代碼以確定是否已正確生成 MSIL等等。

 

3.3.即時編譯JIT

運行CIL (公共中間語言/中間代碼) 前,必須通過CLR(公共語言運行時)將其編譯為目標電腦基礎結構的本機代碼,這個編譯就是由CLR中的即時編譯器(JIT)來完成的

 

即時編譯只有在函數的第一次調用時發生。因為在Class loader(類載入程式)執行的時候會為每個函數插入一個存根。那麼在調用函數時,CLR會檢查函數對應的存根,如果沒有相應的存根,則JIT才會執行編譯,並將該函數被編譯後的本地機器代碼地址寫入到函數對應的存根中。當第二次對同一函數進行調用時,會再次檢查這個存根,如果發現其保存了本地機器代碼的地址,則直接跳轉到本地機器代碼進行執行,而無需再次進行JIT編譯。

另外基於這一現象,我門也從側面知道函數存根中存儲的就是,函數對應的本地機器代碼的地址。

 

通過結合上面文字描述後,我們將其整理繪製出,CLR運行整體工作流程圖:


總結

在實際的生活當中,往往工作了幾年的程式員都沒對.NET框架有一個基本的認識,有的時候還會在面試中被這個方面的問題“卡過喉嚨”。而我個人認為作為一個合格的.Net程式員,理解.NET框架是最基本的素質之一,這也是為了走向更遠的奠基石。

 

如果要深入瞭解更多關於CLR部分的內容,可以瀏覽下方官方地址:

https://docs.microsoft.com/zh-cn/dotnet/standard/clr

 

 

知識改變命運
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 風玫瑰是由氣象學家用於給出如何風速和風向在特定位置通常分佈的簡明視圖的圖形工具。它也可以用來描述空氣質量污染源。 風玫瑰工具使用Matplotlib作為後端。 安裝方式直接使用pip install windrose 導入模塊 Python學習交流Q群:906715085#### import ...
  • 你好呀,我是歪歪。 我最近在 stackoverflow 上看到一段代碼,怎麼說呢。 就是初看一臉懵逼,看懂直接跪下! 我先帶你看看 stackoverflow 上的這個問題是啥,然後引出這段代碼: https://stackoverflow.com/questions/15182496/why-d ...
  • HashMap是大廠java語言的常考點,主要從底層結構,和線程安全等角度來進行考察,考察點比較集中,但是有一定難度 ...
  • 11月8日Spring官方已經強烈建議使用Spring Authorization Server替換已經過時的Spring Security OAuth2.0,距離Spring Security OAuth2.0結束生命周期還有小半年的時間,是時候做出改變了。目前Spring Authorizati ...
  • 本文主要解決兩個問題 * C# Winform高DPI字體模糊. * 高DPI下(縮放>100%), UI設計器一直提示縮放到100%, 如果不重啟到100%,設計的控制項會亂飛. ...
  • 1、導航查詢特點 作用:主要處理主對象裡面有子對象這種層級關係查詢 1.1 無外鍵開箱就用 其它ORM導航查詢 需要 各種配置或者外鍵,而SqlSugar則開箱就用,無外鍵,只需配置特性和主鍵就能使用 1.2 高性能優 查詢 性能非常強悍 支持大數據分頁導航查詢 3.3 語法超級爽 註意:多級查詢時 ...
  • 前言 在Web 應用程式中,我們經常會遇到這樣的場景,如用戶信息,租戶信息本次的請求過程中都是固定的,我們希望是這種信息在本次請求內,一次賦值,到處使用。本文就來探討一下,如何在.NET Core 下去利用AsyncLocal 實現全局共用變數。 簡介 我們如果需要整個程式共用一個變數,我們僅需將該 ...
  • 此次,iNeuOS工業互聯網操作系統升級主要針對三維(3D)模型線上編輯與應用、數據實時統計。用戶有現成的3D模型可以導入到平臺中,模型部件與數據點進行綁定,實時反饋狀態信息到3D模型中。數據實時統計主要後期應用到線上Excel報表中,快速開發和生成時表報、日報表、月報表和年報表等應用。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...