.NET學習筆記 -- 那堆名詞到底是啥(CLR、CLI、CTS、CLS、IL、JIT)


什么是CLR?

CLR,公共語言運行時(Common Language Runtime)是一個由多種語言使用的“運行時”。他的核心功能包括(內存管理、程序集加載、安全性、異常處理和線程同步),可以被面向CLR的所有語言使用。這里的“運行時”,就是一個運行時環境,就像JAVA虛擬機一樣。哦,錯了,確切的說是JRE(Java  Runtime Enviromental)。JVM確切的說不是一個實體的java虛擬機,而是一個規范,就像CLI一樣。會有不同的實現,如:JRockit還是Hotspot(前者是Oracle的JVM商業實現,后者是Sun的開源實現——當然現在也是Oracle的)

什么是CLI?

公共語言基礎結構(Common Language Infrastructure),定義了構成.NET Framework基礎結構的可執行代碼,以及代碼運行時的環境規范。它定義了一個與語言無關的跨體系結構的運行環境,這使得開發者可以用規范內定義的各種高級語言來開發軟件,並且無須修正即可將軟件運行在不同的計算機體系結構上。CLI是一個開放型的技術規范,由微軟、惠普和英特爾於2000年向ECMA倡議的。說白了,CLI就是一套規范,CLR是對CLI的一種實現。那么CLI這份規范中具體定義了哪些內容呢?不妨去ECMA的網站下一份看看,也可以在這里下載:

image

如上面截圖所示:包含了6部分,:

Partition I: Concepts and Architecture –描述.NET CLI的全部體系結構,提供公共類型系統(CTS,Common Type System)、虛擬執行系統(VES,Virtual Execution System)和公共語言規范(CLS,Common Language Specification)的標准化描述,還提供對元數據(Metadata)的信息性描述。

通用類型系統(CTS):規范.NET中數據的類型。

元數據系統(Metadata):是.NET中描述數據的數據。

通用語言規范(CLS):描述多語言之間進行交互的語言規范,.NET系統包括的語言有C#、C++、VB、J#,它們都遵守通用語言規范。

虛擬執行系統(VES):是一個可運行受管理代碼(Managed Code)的運行環境,它提供了運行受管理代碼所需要的內置數據類型(data type),以及假定的機器型態與狀態設置、流程控制與例外處理等參數。

Partition II: Metadata Definition and Semantics - 提供元數據的標准化描述,包括元數據在.NET擴展PE文件格式中的位置(以.NET擴展PE文件格式的形式表示),元數據的邏輯內容(以表格及其關聯的集合的形式表示,實際上使用了形式化方法表示)和元數據的語義(以匯編成為虛擬機代碼的匯編器ilasm理解的形式表示)。

Partition III: CIL Instruction Set描述CIL的指令集(注意,是CIL,不是CLI哦)

Partition IV: Profiles and Libraries- 提供CLI庫的簡要介紹,以及將其分解為Profile和庫的規范。這里有一個配套的文件CLILibraryTypes.xml,考慮過隨這一部分一起發布,不過該文件是XML格式的,該文件提供了CLI庫中每一個類、值類型和接口的細節說明。“Profile”一詞在這里的含義是庫的集合,一起組合起來構成提供一定功能級別的一致性整體,換而言之,不同的Profile對應不同的庫集合,提供的功能級別也不同。

Partition V: Debug Interchange Format- 描述了CLI 產品的調試交互的標志方式;

Partition VI: Annexes- 提供了一些用ILAsm(CIL Assembly Language)寫的例程等

什么是CTS?

CLR是完全圍繞類型展開的,通過類型,通過一種編程語言寫的代碼可以與另一種語言寫的代碼溝通。所以Microsoft制定了一個正式的規范,“通用類型系統”(Common Type System,CTS),它描述了類型的定義和行為。上面已經提到,Microsoft已經將CTS和,NET Framework的其他組件 -- 包括(文件格式、元數字、中間語言及對底層平台的)提交給ECMA完成標准化工作,最終形成的標准稱為“公共語言基礎結構”(Common Language Infrastructure)。

CTS里定義了以下內容:

什么是CLS?

CLR中集成了多種語言,一種語言中可以調用另一種語言創建的對象。為了實現這一目的,微軟定義了一個公共語言規范(Common Language Specification)。它詳細定義了一個最小的功能集。任何編譯器如果想生成類型兼容於其他“符合CLS,面向CLR語言”生成的組件,那么必須要支持這個最小功能集。下面用一張圖來說明彼此間的關系:

image

什么是IL?

image(截自《CLR.via.C#》)

先從上圖看一下.net的編譯過程,源代碼文件經過編譯器編譯后生成托管模塊(managed module)。托管模塊說白了就是一個32位(PE32)或64位(PE32+)的PE文件。

具體的結構如下:

PE32或PE32+文件頭
CLR頭
元數據
IL代碼

這里我們着重談談IL,IL是與CPU無關的機器語言,比大多數的CPU機器語言都要高級。能訪問操作對象類型、創建及初始化對象、調用對象上的虛方法,直接操作數組元素,甚至能拋出和捕捉異常處理,可以說是一種面向對象的機器語言。

什么是JIT?它是如何工作的?

CLR執行托管模塊,必須要將IL代碼編譯成本地CPU指令。這個事情由JIT(just in time)來執行。下面將以一個簡單的例子來詳細闡述JIT是如何工作的:

static void Main()
{
    Console.WriteLine("Hello");
    Console.WriteLine("Goodbye");
}

1、CLR在執行Main函數檢查引用的所有類型,這里Main用到了Console類,CRL會為此分配一個內部結構。在這個結構中,Console類的所有方法都有對應的入口。

2、Mian首次調用WriteLine函數時,JITCCompiler函數會被調用。JITCCompiler知道是Console類定義了WriteLine函數,並在定義了Console類的程序集中查找WriteLine的IL代碼。

3、動態分配一塊內存;

4、對找到的IL代碼進行驗證,然后編譯成本地CPU指令,將該指令放到前面動態分配的內存中;

5、修改內部結構中WriteLine函數的入口,使其指向動態分配的內存的地址;

6、JITCCompiler函數跳轉到存有本地CPU指令;

7、執行完后,調回Main函數,繼續執行后面的代碼;

這里需要說明的是,第二次執行WriteLine函數的時候,並沒有JIT啥事情了,因為會直接調用內存塊中的本地CPU指令。

image

 

參考:《分清“語言/規范”以及“平台/實現”,以及跨平台.NET開發

             《CLR.via.C#》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM