Mono,CLR,.net,Net Framework之间的关系
先粗略看下各自的意義:
- .Net:以下這些技術(shù)的統(tǒng)稱(chēng)。是一個(gè)平臺(tái),而.NET平臺(tái)有一個(gè)實(shí)現(xiàn)標(biāo)準(zhǔn),叫做.Net Standard;
- .Net Framework/.Net Core/Mono:實(shí)現(xiàn)了這個(gè)標(biāo)準(zhǔn),其選擇的組件不一定相同
- CLR:Common Language Runtime 一個(gè)執(zhí)行引擎,用于進(jìn)行一類(lèi)程序(CLI),提供類(lèi)型系統(tǒng)、垃圾回收、JIT等功能;目前有3個(gè)主要實(shí)現(xiàn),分別為coreclr用于.Net Core、desktop clr用于.Net Framework(有了coreclr之后才獲得的一個(gè)相對(duì)”名稱(chēng))、Mono(沒(méi)人給其中的runtime部分單獨(dú)取名)
- CLI:Common Language Infrastructure 一個(gè)經(jīng)標(biāo)準(zhǔn)化組織認(rèn)證的標(biāo)準(zhǔn)(ECMA-335),定義了CLR的基礎(chǔ)功能和其上執(zhí)行的程序的標(biāo)準(zhǔn)
- IL:Intermediate Language 用于將程序直接輸入CLR的格式,包含二進(jìn)制格式與其對(duì)應(yīng)的文本格式;IL中的任何構(gòu)造都與CLR內(nèi)部嚴(yán)格一一對(duì)應(yīng);因?yàn)樵缙谠O(shè)計(jì)預(yù)留了自定義特性的空間,所以其版本十余年不曾變化,各種新功能都使用自定義特性來(lái)表示
- CoreFX:隨CLR一同發(fā)行的發(fā)行的一組子程序與類(lèi)型,任何在CLR上運(yùn)行的程序皆可調(diào)用;其中最底層的部分不能完全用IL表示,有些則是對(duì)CLR自身功能的調(diào)用,而上層可能依賴(lài)對(duì)底層的假設(shè),因此其版本與CLR的版本是綁定的
- C# :一個(gè)編程語(yǔ)言,使用C語(yǔ)系風(fēng)格;除了IL能直接表示的基本功能外,還提供了一些經(jīng)過(guò)一定封裝的功能;每個(gè)功能都可能需要假定CoreFX提供了特定的類(lèi)型來(lái)完成;另兩個(gè)對(duì)應(yīng)的、由第一方支持的編程語(yǔ)言為F#和VB,其功能集和C#不完全一致
- Roslyn:第一方(標(biāo)準(zhǔn)制定者)實(shí)現(xiàn)的編譯器,Mono也實(shí)現(xiàn)了一個(gè)(mcs),二者共同遵循C#語(yǔ)言標(biāo)準(zhǔn)
- .Net Standard:在不同的發(fā)行之間為CoreFX的公開(kāi)接口(即使用方法)及行為規(guī)定標(biāo)準(zhǔn),但不關(guān)心其具體實(shí)現(xiàn)細(xì)節(jié),也允許每個(gè)發(fā)行提供一些額外內(nèi)容
所以可以總結(jié)一下,.net從一個(gè)抽象上來(lái)說(shuō)其實(shí)是一個(gè)理念,即使得多種語(yǔ)言編寫(xiě)的程序能夠通過(guò)一個(gè)通用的runtime運(yùn)行在不同的操作系統(tǒng)以及硬件平臺(tái)上。但光有理念不行,還需要實(shí)現(xiàn),我們這里把對(duì)于.net里面的某個(gè)實(shí)現(xiàn)叫做.net platform(比如.net framework就是一個(gè)在windows上實(shí)現(xiàn)的.net platform,mono則是一個(gè)跨平臺(tái)的.net platform)。一個(gè).net platform想要達(dá)成.net的目標(biāo),就需要一些組件,比如上圖中CLR通用語(yǔ)言運(yùn)行時(shí),比如FCL基礎(chǔ)類(lèi)庫(kù),比如各種語(yǔ)言的編譯器,編譯器編譯出來(lái)的東西想要能在CLR中運(yùn)行,那也需要遵循一定的標(biāo)準(zhǔn),這就是CLI和CIL,CIL規(guī)定了編譯輸出的規(guī)則,而CLI規(guī)定了編譯器輸入語(yǔ)言的規(guī)則,只有符合這種標(biāo)準(zhǔn)的語(yǔ)言才能編譯成CIL語(yǔ)言運(yùn)行在CLR中。
好了現(xiàn)在有了CIL和CLR,程序員可以用符合CLI的語(yǔ)言比如C#編寫(xiě)程序了,然后將其編譯成CIL,最后在CLR中運(yùn)行。但是問(wèn)題來(lái)了,程序員開(kāi)發(fā)程序的時(shí)候需要用到一些功能以及數(shù)據(jù)結(jié)構(gòu),不可能所有的功能細(xì)節(jié)都自己實(shí)現(xiàn),不然開(kāi)發(fā)成本也太高了,所以就需要提供一些基礎(chǔ)類(lèi)庫(kù),方便程序員進(jìn)行開(kāi)發(fā),那么需要提供哪些基礎(chǔ)類(lèi)庫(kù)呢?這也需要一個(gè)標(biāo)準(zhǔn),而.Net Standard就是用于這個(gè)目的,它規(guī)定了某個(gè).net platform需要提供哪些API給開(kāi)發(fā)者。這樣的話加入一個(gè)開(kāi)發(fā)者在.net platform A(比如.net framework)上開(kāi)發(fā)了一個(gè)項(xiàng)目,然后想遷移到.net platform B(比如Mono)上,那么只要兩個(gè)platform實(shí)現(xiàn)了同一個(gè).net standard那么源代碼就無(wú)需修改可以直接編譯運(yùn)行。
不過(guò)還有一個(gè)問(wèn)題,假如我有一臺(tái)機(jī)器,裝了.net platform A(比如.net framework)和.net platform B(比如Mono),那么我在A上編譯出來(lái)的一個(gè).net程序放到B上可以運(yùn)行么?理論上應(yīng)該沒(méi)問(wèn)題,畢竟CIL是統(tǒng)一的,雖然一個(gè)是A的CLR一個(gè)是B的CLR,但是它們都是用來(lái)處理CIL程序,就像java代碼編譯出來(lái)既可以運(yùn)行在JVM上也可以運(yùn)行在delvik上一樣。然而實(shí)際上不一定,因?yàn)镃IL本身也不是一成不變的,它也有自己的版本,看下面這個(gè)文檔:
https://msdn.microsoft.com/en-us/library/bb822049.aspx
里面的表格詳細(xì)說(shuō)明了.net framework和CLR版本之間的關(guān)系,從.net framework 2.0到3.5使用的是CLR 2.0,.net framework 4.0以后使用的是CLR 4.0,中間沒(méi)有CLR 3.0版本。這也就意味著CIL語(yǔ)言本身也在發(fā)生變化,面向CLR 4.0編譯出來(lái)的程序自然是不能運(yùn)行在CLR 2.0上的。
說(shuō)那到底什么是.net framework呢?個(gè)人理解從抽象角度說(shuō).net framework是對(duì).net標(biāo)準(zhǔn)(這個(gè)標(biāo)準(zhǔn)具體包括CLI,CIL,.net standard等)在windows平臺(tái)上的一套實(shí)現(xiàn),具體上說(shuō).net framework包含一整套解決方案,包含許多字組件,比如編譯器、CLR、FCL等等,其中每個(gè)組件都有自己的版本,比如編譯器有自己的版本用于適應(yīng)不同版本的語(yǔ)言,比如.net framework 3.5的編譯器只支持到C# 3.0,最新已經(jīng)到C# 7.0了;每個(gè)版本的.net framework提供的FCL也在不斷豐富,比如System.LINQ到.net framework 3.5才有;CLR的版本也會(huì)不同,之前已經(jīng)說(shuō)過(guò)了。因此.net framework的版本其實(shí)就是其組件版本的一個(gè)集合,高版本的.net framework中的每個(gè)子組件都進(jìn)行了一定的版本更新。
隨著.NET Core Framework的開(kāi)發(fā)完成,.NET Framework與Mono將基于.NET Core重新構(gòu)建。.NET Framework將成為.NET Core在Windows上的一個(gè)發(fā)行版,Mono將成為.NET Core的一個(gè)跨平臺(tái)發(fā)行版。
對(duì)于Unity中PlayerSetting中的設(shè)置 API Compatibility Level,指的是實(shí)現(xiàn)的.Net標(biāo)準(zhǔn)
關(guān)于Mono和CLR的GC:
1.mono早期使用的是Boehm-Demers-Wiser GC庫(kù),后期更新為有分代和多線程能力的SGen庫(kù)
2.這里需要強(qiáng)調(diào)一下,由于歷史原因,unity使用版本比較老的mono,然后在其基礎(chǔ)上做了很多修改,以及整合外圍的一些新功能,導(dǎo)致的結(jié)果是無(wú)法跟進(jìn)最新版本的mono,這也是為什么GC還是最老的Boehm-Demers-Wiser庫(kù)。所以如果想自己嘗試整合最新的mono,很可能會(huì)搞成一坨坨。
3.然后,還不能忘了il2cpp,這是完全獨(dú)立的一個(gè)runtime,編譯成il2cpp就意味著跟mono沒(méi)有關(guān)系了,這時(shí)他也有自己的一套GC實(shí)現(xiàn),很不幸依然使用了老舊的Boehm-Demers-Wiser GC。。
4.mono在語(yǔ)法、編譯、runtime、庫(kù)等等層面上確實(shí)執(zhí)行了.net的標(biāo)準(zhǔn),但是GC的底層實(shí)現(xiàn)上至少早期是沒(méi)有明確規(guī)定怎么實(shí)現(xiàn)底層的,就算有,mono因?yàn)槲④洸还_(kāi)代碼的原因,當(dāng)時(shí)也不得不自己摸索一套方案,于是也就有了現(xiàn)在跟.net毫無(wú)關(guān)聯(lián)的GC實(shí)現(xiàn)。
5.最新的Unity已經(jīng)加入了incremental GC
?
?總結(jié)
最后用圖總結(jié)下:
1. .NetFramework/.Net Core/Mono實(shí)現(xiàn)了.Net標(biāo)準(zhǔn)
2. .NetFramework 運(yùn)行平臺(tái)為PC,Mono 和 .NetCore是跨平臺(tái)的。
3. Mono有自身實(shí)現(xiàn)的CLR,即MonoVM,最早的GC版本用的是BoehmGC,也就是Unity用的GC
4. 最新的Unity已經(jīng)加入了incremental GC
5. IL2CPP也借助Mono編譯器,Mono編譯器生成的IL代碼通過(guò)IL2CPP轉(zhuǎn)成C++文件,再通過(guò)C++的IL2CPP的VM獲得跨平臺(tái)特性
6. IL2CPP用的GC也是BoehmGC,最新的Unity可以用incremental GC
?
?
參考資料:
?
?
https://www.zhihu.com/question/317261730
https://www.cnblogs.com/w-wfy/p/7450167.html
https://docs.microsoft.com/en-us/visualstudio/cross-platform/unity-scripting-upgrade?view=vs-2019
https://www.cnblogs.com/u3ddjw/p/10909975.html
https://www.cnblogs.com/shanyou/p/4295163.html
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Mono,CLR,.net,Net Framework之间的关系的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 聂远送限量礼包《铁血龙魂》超值礼包领取指
- 下一篇: GPU Skin