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