.NET學(xué)習(xí)筆記 -- 那堆名詞到底是啥(CLR、CLI、CTS、CLS、IL、JIT)
什么是CLR?
CLR,公共語言運行時(Common Language Runtime)是一個由多種語言使用的“運行時”。他的核心功能包括(內(nèi)存管理、程序集加載、安全性、異常處理和線程同步),可以被面向CLR的所有語言使用。這里的“運行時”,就是一個運行時環(huán)境,就像JAVA虛擬機一樣。哦,錯了,確切的說是JRE(Java Runtime Enviromental)。JVM確切的說不是一個實體的java虛擬機,而是一個規(guī)范,就像CLI一樣。會有不同的實現(xiàn),如:JRockit還是Hotspot(前者是Oracle的JVM商業(yè)實現(xiàn),后者是Sun的開源實現(xiàn)——當(dāng)然現(xiàn)在也是Oracle的)
什么是CLI?
公共語言基礎(chǔ)結(jié)構(gòu)(Common Language Infrastructure),定義了構(gòu)成.NET Framework基礎(chǔ)結(jié)構(gòu)的可執(zhí)行代碼,以及代碼運行時的環(huán)境規(guī)范。它定義了一個與語言無關(guān)的跨體系結(jié)構(gòu)的運行環(huán)境,這使得開發(fā)者可以用規(guī)范內(nèi)定義的各種高級語言來開發(fā)軟件,并且無須修正即可將軟件運行在不同的計算機體系結(jié)構(gòu)上。CLI是一個開放型的技術(shù)規(guī)范,由微軟、惠普和英特爾于2000年向ECMA倡議的。說白了,CLI就是一套規(guī)范,CLR是對CLI的一種實現(xiàn)。那么CLI這份規(guī)范中具體定義了哪些內(nèi)容呢?不妨去ECMA的網(wǎng)站下一份看看,也可以在這里下載:
如上面截圖所示:包含了6部分,:
Partition I: Concepts and Architecture –描述.NET CLI的全部體系結(jié)構(gòu),提供公共類型系統(tǒng)(CTS,Common Type System)、虛擬執(zhí)行系統(tǒng)(VES,Virtual Execution System)和公共語言規(guī)范(CLS,Common Language Specification)的標(biāo)準(zhǔn)化描述,還提供對元數(shù)據(jù)(Metadata)的信息性描述。
通用類型系統(tǒng)(CTS):規(guī)范.NET中數(shù)據(jù)的類型。
元數(shù)據(jù)系統(tǒng)(Metadata):是.NET中描述數(shù)據(jù)的數(shù)據(jù)。
通用語言規(guī)范(CLS):描述多語言之間進(jìn)行交互的語言規(guī)范,.NET系統(tǒng)包括的語言有C#、C++、VB、J#,它們都遵守通用語言規(guī)范。
虛擬執(zhí)行系統(tǒng)(VES):是一個可運行受管理代碼(Managed Code)的運行環(huán)境,它提供了運行受管理代碼所需要的內(nèi)置數(shù)據(jù)類型(data type),以及假定的機器型態(tài)與狀態(tài)設(shè)置、流程控制與例外處理等參數(shù)。
Partition II: Metadata Definition and Semantics - 提供元數(shù)據(jù)的標(biāo)準(zhǔn)化描述,包括元數(shù)據(jù)在.NET擴展PE文件格式中的位置(以.NET擴展PE文件格式的形式表示),元數(shù)據(jù)的邏輯內(nèi)容(以表格及其關(guān)聯(lián)的集合的形式表示,實際上使用了形式化方法表示)和元數(shù)據(jù)的語義(以匯編成為虛擬機代碼的匯編器ilasm理解的形式表示)。
Partition III: CIL Instruction Set –描述CIL的指令集(注意,是CIL,不是CLI哦)
Partition IV: Profiles and Libraries- 提供CLI庫的簡要介紹,以及將其分解為Profile和庫的規(guī)范。這里有一個配套的文件CLILibraryTypes.xml,考慮過隨這一部分一起發(fā)布,不過該文件是XML格式的,該文件提供了CLI庫中每一個類、值類型和接口的細(xì)節(jié)說明。“Profile”一詞在這里的含義是庫的集合,一起組合起來構(gòu)成提供一定功能級別的一致性整體,換而言之,不同的Profile對應(yīng)不同的庫集合,提供的功能級別也不同。
Partition V: Debug Interchange Format- 描述了CLI 產(chǎn)品的調(diào)試交互的標(biāo)志方式;
Partition VI: Annexes- 提供了一些用ILAsm(CIL Assembly Language)寫的例程等
什么是CTS?
CLR是完全圍繞類型展開的,通過類型,通過一種編程語言寫的代碼可以與另一種語言寫的代碼溝通。所以Microsoft制定了一個正式的規(guī)范,“通用類型系統(tǒng)”(Common Type System,CTS),它描述了類型的定義和行為。上面已經(jīng)提到,Microsoft已經(jīng)將CTS和,NET Framework的其他組件 -- 包括(文件格式、元數(shù)字、中間語言及對底層平臺的)提交給ECMA完成標(biāo)準(zhǔn)化工作,最終形成的標(biāo)準(zhǔn)稱為“公共語言基礎(chǔ)結(jié)構(gòu)”(Common Language Infrastructure)。
CTS里定義了以下內(nèi)容:
什么是CLS?
CLR中集成了多種語言,一種語言中可以調(diào)用另一種語言創(chuàng)建的對象。為了實現(xiàn)這一目的,微軟定義了一個公共語言規(guī)范(Common Language Specification)。它詳細(xì)定義了一個最小的功能集。任何編譯器如果想生成類型兼容于其他“符合CLS,面向CLR語言”生成的組件,那么必須要支持這個最小功能集。下面用一張圖來說明彼此間的關(guān)系:
什么是IL?
先從上圖看一下.net的編譯過程,源代碼文件經(jīng)過編譯器編譯后生成托管模塊(managed module)。托管模塊說白了就是一個32位(PE32)或64位(PE32+)的PE文件。
具體的結(jié)構(gòu)如下:
| PE32或PE32+文件頭 |
| CLR頭 |
| 元數(shù)據(jù) |
| IL代碼 |
這里我們著重談?wù)処L,IL是與CPU無關(guān)的機器語言,比大多數(shù)的CPU機器語言都要高級。能訪問操作對象類型、創(chuàng)建及初始化對象、調(diào)用對象上的虛方法,直接操作數(shù)組元素,甚至能拋出和捕捉異常處理,可以說是一種面向?qū)ο蟮臋C器語言。
什么是JIT?它是如何工作的?
CLR執(zhí)行托管模塊,必須要將IL代碼編譯成本地CPU指令。這個事情由JIT(just in time)來執(zhí)行。下面將以一個簡單的例子來詳細(xì)闡述JIT是如何工作的:
static void Main() { Console.WriteLine("Hello"); Console.WriteLine("Goodbye"); }
1、CLR在執(zhí)行Main函數(shù)檢查引用的所有類型,這里Main用到了Console類,CRL會為此分配一個內(nèi)部結(jié)構(gòu)。在這個結(jié)構(gòu)中,Console類的所有方法都有對應(yīng)的入口。
2、Mian首次調(diào)用WriteLine函數(shù)時,JITCCompiler函數(shù)會被調(diào)用。JITCCompiler知道是Console類定義了WriteLine函數(shù),并在定義了Console類的程序集中查找WriteLine的IL代碼。
3、動態(tài)分配一塊內(nèi)存;
4、對找到的IL代碼進(jìn)行驗證,然后編譯成本地CPU指令,將該指令放到前面動態(tài)分配的內(nèi)存中;
5、修改內(nèi)部結(jié)構(gòu)中WriteLine函數(shù)的入口,使其指向動態(tài)分配的內(nèi)存的地址;
6、JITCCompiler函數(shù)跳轉(zhuǎn)到存有本地CPU指令;
7、執(zhí)行完后,調(diào)回Main函數(shù),繼續(xù)執(zhí)行后面的代碼;
這里需要說明的是,第二次執(zhí)行WriteLine函數(shù)的時候,并沒有JIT啥事情了,因為會直接調(diào)用內(nèi)存塊中的本地CPU指令。
參考:《分清“語言/規(guī)范”以及“平臺/實現(xiàn)”,以及跨平臺.NET開發(fā)》
《CLR.via.C#》





浙公網(wǎng)安備 33010602011771號