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.mzph.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…