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

什麼是CLR?html

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

什麼是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#,它們都遵照通用語言規範。spa

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

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");
}

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

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

三、動態分配一塊內存;

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

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

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

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

這裏須要說明的是,第二次執行WriteLine函數的時候,並無JIT啥事情了,由於會直接調用內存塊中的本地CPU指令。

image

 

參考:《分清「語言/規範」以及「平臺/實現」,以及跨平臺.NET開發

             《CLR.via.C#》

相關文章
相關標籤/搜索