Unity的未來,是固守Mono,還是擁抱CoreCLR?

TLDR;

Unity堅定的擁抱.NET標準生態,正全速向CoreCLR遷移。

Mono vs CoreCLR

對于一個C#的初學者,首先要了解的便是.NET和C#的關系。所以這里不再贅述。對于一個Unity的初學者,在使用C#編碼的過程中,一定會遇到一些C#新特性不能在項目中使用的情況,這是因為微軟官方提供的.NET運行時環境(最新版為 .NET 6 的?CoreCLR)遠比Unity集成的Mono強大。由于歷史原因,Unity一直未能使用最新的.NET運行時。本文就來細說一下其中的歷史,以及Unity未來的發展。

首先,Mono是.NET的開源實現,由Xamarin牽頭維護 mono/mono 這個repo。2016年Xamarin被微軟收購,將其license從GPL改成了MIT,同時微軟也參與到Mono的開發中。在微軟的 dotnet/runtime 這個repo中,可以發現mono,但這并不是mono/mono的替代品,而是微軟為了方便其他組件開發,將部分代碼拷貝過來進行魔改,在需要的時候同步回mono/mono。(出處:Announcement: Consolidating .NET)

然后說一下?CoreCLR。微軟改名部絕非浪得虛名,這些年的一系列改名操作把好端端的.NET技術攪成一灘渾水。非常簡要的說,過去.NET運行時只能用于Windows平臺,名為 .NET Framework,運行時叫CLR,大名鼎鼎的《CLR via C#》就是基于該運行時。后來微軟決定將.NET技術開源,并徹底地跨平臺(Windows,Linux,MacOS等),順便大幅提高運行效率并拋棄一些舊組件,重寫了一版 .NET Core,運行時叫?CoreCLR。雙線開發并不是個好主意,因此再后來微軟決定將前者廢棄,以 .NET Core相關技術為核心,將.NET技術大一統(桌面開發、移動開發、游戲開發、IoT開發、云開發等等),史稱 .NET 5。因此,往后.NET的官方運行時就叫CoreCLR。repo在這里:dotnet/runtime。

大一統的餅是畫出來了,但當下移動平臺的.NET開發的主流還是Mono。這里結合Wiki,對Mono的重要歷史加以整理。

  • 2010年9月,Mono2.8發布,帶來了新的分代式GC:SGen;支持 C#4;支持 .NET 4.0。

  • 2013年7月,Mono3.2發布,SGen取代Boehm成為默認的GC。

  • 2015年4月,Mono4.0發布,開始集成 .NET Core;支持 C#6。

  • 2017年5月,Mono5.0發布,開啟了concurrent SGen;使用Roslyn編譯器;支持 C#7。

  • 2019年9月,Mono6.4發布,支持?.NET Standard 2.1;支持 .NET 4.8。

然而Mono對.NET的特性支持和性能一直落后于微軟官方的CLR,性能上也大幅落后于CoreCLR(補充:2018年Unity的官方數據是CLR比Mono快30%-3倍。Mono這些年的進步有目共睹,但奈何不了微軟爸爸的鈔能力給CoreCLR研發上的加成。經過4年的發展,一些民間測試資料已顯示CoreCLR比Mono快10-20倍,比IL2CPP快8-10倍)。

過去,Unity 選擇 Mono

上文理清了Mono?和CoreCLR的關系,下面說說Unity在這二者間的選擇。

早在2008年,Unity就宣布和Mono合作,但后續Mono新版本使用SGen GC取代Boehm GC時,Unity不想再次付許可證費用。直到2021年7月,Unity依然依賴 Boehm GC。這是一種沒有分代的(掃描慢)、Mark-Sweep的(會有內存碎片問題)、保守(不能精確地識別垃圾)的GC。

Unity has been and is still relying on the?Boehm GC, which is a conservative (stack-root) GC. The link above doesn't go into some details like how managed objects on the stack are collected by the GC, but basically: a conservative GC will scan the entire stack of all managed threads to "pin" memory referenced by it. Because of this blind scan, it can bring false pin, because it can interpret an integer value, as a pointer to a region of the heap memory, while it was really an int in the first place. By doing so, a conservative GC can start to block some objects from being collected (or worse for a moving-generational GC, to relocate objects). Otoh, a precise GC is able to scan precisely stack-roots and report only pointers that actually point to heap memory. In order for a precise GC to work, the (JIT) codegen needs to be GC aware, which is the case for CoreCLR.

對于Boehm GC造成的性能問題,Unity官方有一些折中方案。

  • 先盡量分配好所有對象的內存,然后關閉GC,等到合適的時機(如關卡結束),再開啟GC;

  • 默認開啟 incremental 模式分幀處理,注意如果在期間有大量引用關系的改寫,分幀處理反而會有大量額外性能損耗(主要來自寫屏障)

未來,Unity 選擇 CoreCLR

自2016年微軟將Mono的許可證由GPL改為MIT以來,Unity也加入了?.NET Foundation,開始將最新的Mono集成到自己的引擎中。但隨著微軟構筑開源的大一統解決方案 .NET 5,Unity似乎改變了原先的想法。從官方論壇中可以總結出他們的規劃:

  1. 首先集成最新的Mono,因為其支持 .NET Core 的BCL;

  2. 然后將自家的 IL2CPP 也更新(其依賴Mono的輸出結果);

  3. Unity 2021.2開始完全支持.NET Standard 2.1,C#8和部分C#9(Span,Range,default interface methods),其中Span的影響非常深遠,目前和BurstCompiler的NativeArray還不能無縫轉換,最大難點是Span并沒有自己的memory但后者有;

  4. 支持 C#9/10,基于前面的工作,這一步并不難;

  5. 支持 .NET 6(跳過 .NET 5)。但有兩大難題:

  • 所有dll必須重新編譯;

  • 要修改 UnityEditor 中大量使用 AppDomain進行hot reload的部分(AppDomain在新版.NET中幾乎被廢棄,出處);目前的替代類 AssemblyLoadContext 并不能提供之前 AppDomain Reload的所有功能。

In general Assembly Load Context is cooperative, and any remaining references (static fields, GC Handles, running threads, etc) will prevent the code from being unloaded.

6. 用CoreCLR替代Mono(GC也相應升級為CoreCLR GC),在此之前,GC并不會升級為Mono的SGen。這項工作會持續比較久,目前還沒有ETA。Unity大部分代碼是C++,C#只有薄薄的一層(但是越來越多的代碼在切換到 C#)。在切換到CoreCLR后,其訪問Managed Object的方式需要徹底改變,因此改動會很大。總體順序是:先將Player替換為CoreCLR,然后將Editor也替換掉。

長遠來看,Unity該團隊已經意識到自己當年的一些輪子(Coroutine, Customized Boehm GC, IL2CPP, asmdef等)在近幾年來.NET運行時、工具鏈和整套生態的飛速發展面前顯得有些陳舊,正在致力于向開發者提供原汁原味的.NET開發體驗(出處),同時盡量不顛覆原有的使用習慣(例如出于這些原因,UPM不會和NuGet雙向互通)。

另外,Unity團隊還有很多高優先級的feature要做,希望Unity越來越好吧。最新消息可關注官方論壇的討論:

Unity Future .NET Development Status - Unity Forumforum.unity.com/threads/unity-future-net-development-status.1092205/

另外,文中提到的《CLR via C#》雖然內容基于 .NET Framework,但由于大部分內容在 .NET5+ 中并沒有變化,該書憑借其內容深入和廣度,依然是 C# 進階學習的必讀經典。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280708.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280708.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280708.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

hinton教授的本科生課程CSC321-機器學習中的神經網的筆記

最近一直在看仙守博友所記錄的筆記 Hinton的CSC321課程(完結,待文字潤色): 1、lecture1-NN的簡介 2、lecture2-NN結構的主要類型的概述和感知機 3、lecture3-線性神經元和算法 4、lecture4-神經網絡在語言上的應用 5、lecture5-對…

ASP存儲過程參數數據類型

ASP調用存儲過程一般的方法: p.Append cmd.CreateParameter("參數名稱",類型,方向,大小) 參許參數值的類型的意義如下: 名稱值 整數值 功能 adDBTimeStamp 135 日期時間數據類型 adDecimal 14 十進制整數值 adDouble …

powershell 啟動線程與關閉線程

啟動線程 $ScreenCapture"C:\ResolutionTool\ScreenCapture.exe" Start-Process $ScreenCapture 關閉線程 Get-Process ScreenCapture| Stop-Process

HDU 5673 Robot 卡特蘭數

題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid5673 題目描述: 一個人從原點開始向右走, 要求N秒后回到原點, 且過程中不能到負半軸, 人有兩種操作, 走動或者停止, 問總共有多少種方案&…

刪除本地賬戶無法登錄電腦_如何從Windows的登錄屏幕中刪除本地用戶帳戶

刪除本地賬戶無法登錄電腦If you have multiple user accounts on your computer, you might find it annoying to have to click on the icon for your username each time you start up the computer. To remedy this problem, you can hide a user account with a registry …

tarjan算法詳解

https://blog.csdn.net/jeryjeryjery/article/details/52829142?locationNum4&fps1 以防鏈接失效,特此轉載此博,如有侵權請見諒 在有向圖G中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通(strongly connected)。如果有向…

Gitlab簡單使用CI/CD

開篇語大概是去年就想做這個事情了,奈何當時卡到一個docker命令找不到的問題上,導致文章難產了,墨跡了這么久,終于又有空來搗鼓它了。目的我們要實現的目的是我本地不斷提交代碼(CI),然后服務器不斷進行部署(CD)的一個簡單流程。準…

AppleScript: Handler

AppleScript絕對是個奇葩的存在!不管功能有多強大。 Handler有兩種,一種是和OC類似的使用Label參數,一種是和javascript類似的使用括號把一堆參數都放在里面的。 label參數的Handler的寫法非常奇怪,光看文檔絕對讓人迷糊。這里按照…

powershell 運行策略

Unrestricted 這是一種比較寬容的策略,允許運行未簽名的腳本。對于從網絡上下載的腳本,在運行前會進行安全性提示: Set-ExecutionPolicy UnRestricted

免費的數字圖書館_不僅是書籍:您當地圖書館可能提供的所有免費數字資料

免費的數字圖書館You might think of libraries as old fashioned, or irrelevant in the age of the internet. You’d be wrong. 您可能會認為圖書館是老式的,或者與互聯網時代無關。 你會錯的。 Modern libraries offer books, yes, but they also provide inter…

iNeuOS工業互聯網操作系統,腳本化實現設備運行時長和效率計算與統計

目 錄1. 概述... 22. 實時采集開停狀態... 23. 增加虛擬設備... 24. 腳本統計和計算設備運行時長... 45. 設備運行時長報表... 71. 概述有一個煤礦項目,使用iNeuOS系統時有一個需要是:要統計設備的運行時長&#xff0c…

webpack二(以webpack4.x起步)

一.基本安裝首先我們要創建一個目錄,初始化npm,以及在本地安裝webpack:復制代碼mkdir webpackapp && cd webpackapp復制代碼npm init -y復制代碼npm install --save-dev webapck復制代碼現在我們看一下我們創建的目錄以及目錄下的結構…

阿里云中間件是什么-阿里云中間件介紹

阿里云中間件是什么?這其實是一個比較虛的概念。廣義的中間件范圍很廣。起溝通作用的都可以認為是中間件。甚至ODBC這樣的東西你也可以認為是中間件。 使用了中間件之后,以前直接連接的前臺應用程序和數據庫之前就多了個中間件,現在前臺程序把請求發給…

C# 圖片、文件等加入Project Resources

一、目的 1.編譯后,只想有一個exe文件,不想外部文件引用,直接運行exe文件即可。 2.不會出現文件丟失情況。 二、操作 1.右擊project ->properties->Resource,左上角選擇Image(或其他類型) 2. 點擊…

jfinal使用shiro注解大體流程

2019獨角獸企業重金招聘Python工程師標準>>> 上一篇答題梳理了jfinal整合shiro的流程,jfinal讀取shiro注解,這一篇將作為補充。 1.JFinalShiroPlugin作者為shiro的RequiresRoles,RequiresPermissions, RequiresAuthent…

chrome 快捷鍵取消_如何使用鍵盤快捷鍵在Chrome和Firefox中固定和取消固定選項卡...

chrome 快捷鍵取消If you tend to open a lot of tabs in your browser, it can become difficult to find the tabs with your most used websites. Pinning tabs in your browser moves those tabs to the left and shrinks the tabs to only show the favicon, and you can …

.NET Conf China 2022參會指南速覽(內含超多福利)趕緊預約!???

12月充滿驚喜各種美好節日紛至沓來似在獎勵一年辛苦勞作的你12月的第一波福利.NET Conf China 承包啦立即掃碼預約加入.NET年度盛宴搶12月第一波驚喜!.NET Conf China 2022 .NET Conf China 2022是面向開發人員的社區峰會,延續 .NET Conf 2022 的活動&a…

python導入模塊--案例

1 導入模塊 1.1 問題 本案例要求先編寫一個star模塊,主要要求如下: 建立工作目錄 ~/bin/創建模塊文件 ~/bin/star.py模塊中創建pstar函數,實現打印50個星號的功能然后練習導入模塊,調用模塊中的函數: 在交互解釋器中導…

css常用命名

常用的CSS命名 頭:header 內容:content/container 尾:footer 導航:nav 側欄:sidebar 欄目:column 頁面外圍控制整體佈局寬度:wrapper 左右中:left right center 登錄條:l…

***關于WP的郵件無法發送問題的總結(原創)

1.用FTP打開 /wp-include/class-smtp.php ,最好是下載下來,搜索一下,查找到如下的代碼: $this->smtp_conn stream_socket_client($host . ":" . $port,$errno,$errstr,$timeout,STREAM_CLIENT_CONNECT,$socket_cont…