Mono与IL2CPP
Mono:
Mono是.NET Framework 的一种开源实现。 Mono项目将使开发者用各种语言(C#,VB.NET等)开发的.NET应用程序,能在任何Mono支持的平台上运行, 包括Linux, Unix。Mono项目将使大家能开发出各种跨平台的应用程序, 并能极大提高开源领域的开发效率。
Mono VM (Virtual Machine 虚拟机):
是.net—framework实现跨平台的重要部分,只要在对应平台支持MonoVM就可生机器码,这一关键的步骤同时也是它的缺陷(如WebGL就不支持mono),在unity这种多平台开发工具就会受到一定的限制,对此unity也推了原生的IL2CPP解决跨平台的方案
Mono的三种编译模式:
即时编译(Just in time,JIT):程序运行过程中,将IL代码转为对应平台原生码并且将原生码映射到虚拟内存中执行。JIT编译的时候IL是在依托Mono运行,转为对应的原生码后在依托本地运行。(ios静止这种机器码映射到内中运行的方式,ios只支持AOT提前编译直接在内存运行)
提前编译(Ahead of time,AOT):程序运行之前,将.exe或.dll文件中的CIL的byte code部分转译为目标平台的原生码并且存储,程序运行中仍有部分CIL的byte code需要JIT编译。
完全静态编译(Full ahead of time,Full-AOT):程序运行前,将所有源码编译成目标平台的原生码。
JIT与AOT
AOT(Ahead of Time)编译是一种编译技术,其中代码在程序运行之前就被编译成机器码,而不是在运行时由解释器或即时编译器动态地将代码转换成机器码。在AOT编译下,生成的机器码可以直接在内存中使用,因为它们已经是本地的机器指令,不再需要动态编译或解释。
相比之下,JIT(Just-In-Time)编译是在程序运行时将字节码或其他中间表示形式的代码动态编译成本地机器码。在JIT编译模式下,生成的机器码通常会被映射到内存中,并在需要时执行。这种映射的方式可以提高执行效率,因为它允许操作系统对内存页面进行优化,例如内存保护和虚拟内存管理。
内存映射:
是一种将文件内容映射到内存地址空间的技术。在这种情况下,编译后的机器码通常会被写入一个文件中,然后通过内存映射的方式将文件内容加载到进程的地址空间中。这样做有几个好处:
节省内存开销:将文件内容映射到内存中意味着不需要将整个文件内容复制到进程的地址空间中,而是直接在需要时映射文件的部分内容。这样可以节省内存开销,特别是对于大型文件来说尤为重要。
文件内容更新:如果编译后的机器码发生变化,例如进行了更新或修复,只需要重新映射文件内容而不需要重新加载整个文件,这样可以提高效率。
跨平台兼容性:内存映射是一种通用的技术,在不同的操作系统上都有相应的实现。这样一来,使用内存映射可以提高跨平台兼容性,使得运行时可以更容易地在不同的操作系统上运行。
优缺点:
构建应用非常快
由于Mono的JIT(Just In Time compilation ) 机制, 所以支持更多托管类库
支持运行时代码执行
必须将代码发布成托管程序集(.dll 文件 , 由mono或者.net 生成 )
Mono VM在各个平台移植异常麻烦,有几个平台就得移植几个VM(WebGL和UWP这两个平台只支持 IL2CPP)
Mono版本授权受限,C#很多新特性无法使用
iOS仍然支持Mono , 但是不再允许Mono(32位)应用提交到Apple Store
重点梳理:
Mono打包的主要流程:c# script,unity spcript 和第三方库代码,通过编译器转成 il code中间语言,这时aot与与jit两种变异模式就产生的差别,jit模式下il与mono虚拟机会一起打入包中,il code在应用程序中通过mono虚拟机解释代码将指令映射到虚拟内存执行(ios下禁止这一行为),而aot模式会生成相应平台的机器码,不会将mono虚拟机打入包中。使用 Mono AOT 编译模式可以提高应用程序的启动速度和运行时性能,因为它将 IL 代码编译为本地机器码,减少了运行时的解释和优化过程。这使得应用程序在设备上的运行更加高效和稳定。
一般不会结合jit、aot两种方式打包,除非有特特殊的需求,并且需要额外的复杂逻辑处理
IL2CPP:
在il2cpp中,cpp指的是"C++",它是一种通用的编程语言,用于开发高效且可移植的应用程序。C++在游戏开发中广泛使用,因为它具有高性能和灵活性。在il2cpp中,C++用于编写Unity游戏引擎的运行时库和其他相关代码
IL2CPP AOT编译器名为il2cpp.exe。在Windows上,您可以在Editor \ Data \ il2cpp目录中找到它。
il2cpp.exe :是由C#编写的受托管的可执行程序,它接受我们在Unity中通过Mono编译器生成的托管程序集,并生成指定平台下的C++代码。一旦将Unity应用中的代码转换为C++代码,就可以在移动平台上执行。在使用il2cpp进行编译后,Unity将生成包含C++代码的本机可执行文件,可以在移动设备上运行。这样可以提高应用的性能和执行效率,并且可以更好地利用底层硬件功能和优化。
CPP代码如何执行:
大多数移动平台都支持执行C++代码,但具体支持的程度可能会有所不同。以下是一些主流移动平台的情况:
Android:Android平台原生支持执行C++代码,可以使用Android NDK来开发和运行C++代码。
iOS:iOS平台也原生支持执行C++代码,可以使用Xcode等工具来编译和运行C++代码。
Windows Phone:Windows Phone平台原生支持执行C++代码,可以使用Visual Studio等工具来编译和运行C++代码。
Unity支持的其他平台:Unity引擎可以将C#或Unity脚本转换为C++代码,然后再由各个平台的C++编译器直接编译成能执行的原生汇编代码,从而做到跨平台应用。
需要注意的是,不同平台的编译器和工具链可能有所不同,因此在开发时需要针对具体平台做相应的配置和调整。
优缺点:
相比Mono, 代码生成有很大的提高
可以调试生成的C++代码
可以启用引擎代码剥离(Engine code stripping)来减少代码的大小
程序的运行效率比Mono高,运行速度快
多平台移植非常方便
相比Mono构建应用慢
只支持AOT(Ahead of Time)编译
重点梳理:
il2cpp打包的主要流程:c# script,unity spcript 和第三方库代码,通过编译器转成 il code中间语言,IL2CPP工具 将 il code转换为等效的 C++ 代码,并保留类型信息、方法调用等关键信息。生成的 C++ 代码经过优化和整理后生产本地源码,生成的本地源码包含了一些运行时库(所谓的il2cpp运行时库)的功能,将 .NET 的垃圾回收等功能嵌入到生成的 C++ 代码中,以便在运行时管理内存的分配和释放,
因此,IL2CPP 的运行时库在应用程序运行时起作用,它们负责处理应用程序的运行时行为,包括内存管理、类型转换、异常处理等。这些库是作为编译后的应用程序的一部分打包到最终的可执行文件中的,而不是作为独立的组件进行加载。
总之,IL2CPP 的运行时库在编译后的应用程序运行时扮演着关键的角色,提供了 .NET 的运行时支持和功能。
Mono与IL2CPP的更多相关文章
- Mono vs IL2CPP
[Mono vs IL2CPP] 参考:http://blog.csdn.net/gz_huangzl/article/details/52486255
- [Unity移动端]Mono与IL2Cpp
参考链接: https://blog.csdn.net/linxinfa/article/details/87358809 https://blog.csdn.net/Aison_/article/d ...
- Unity上线google商店 用IL2Cpp打包64位版本和Android APP Bundle优化 及产生的bug
ios刚上线,这边着手改成android版本,我开始使用的是unity2017.4.1版本 上传谷歌商店是出现这两个警告: 要支持64位,但是在2017版本上没有找到64位的打包选项,猜测应该是版本的 ...
- Understanding the managed heap
Understanding the managed heap Another common problem faced by many Unity developers is the unexpe ...
- Unity 5 Game Optimization (Chris Dickinson 著)
1. Detecting Performance Issues 2. Scripting Strategies 3. The Benefits of Batching 4. Kickstart You ...
- unity update优化
http://forum.china.unity3d.com/thread-13968-1-1.html Unity有个消息系统,它可以在运行中当发生指定事件时调用你在脚本中定义的那些魔术方法.这是个 ...
- 不要忽视Managed code stripping的副作用
0x00 前言 Unity 2018.3之后,新的“Managed Stripping Level”选项将替换 player settings 中原有的“Stripping Level”选项. 这个新 ...
- Unity 将是驱动 C# 增长的引擎吗 ?
C# 在中国的采用需要一个杀手级应用的带动, 那么这样的一个杀手级应用是 Unity吗,我这里大胆推测采用CoreCLR 的新一代完全采用C#构建的Unity 将是这样的一个杀手级应用.Unity已被 ...
- Mono为何能跨平台?聊聊CIL(MSIL)
前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...
- 从Unity3D编译器升级聊起Mono
接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识. Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的M ...
随机推荐
- 【Netty】(3)—源码NioEventLoopGroup
netty(3)-源码NioEventLoopGroup 一.概念 NioEventLoopGroup对象可以理解为一个线程池,内部维护了一组线程,每个线程负责处理多个Channel上的事件,而一个C ...
- 利用坦克PWA3快速为应用配置域名:以Gogs为例
全文概述 本文介绍了如何利用坦克PWA3平台快速为Gogs应用配置域名的过程.随着互联网技术的发展,自托管Git服务变得越来越受欢迎,其中Gogs凭借其轻量级和易于安装的特点受到众多开发者的青睐.为提 ...
- CompletableFuture 超时功能有大坑!使用不当直接生产事故!
CompletableFuture 超时功能有大坑!使用不当直接生产事故! 本文未经允许禁止转载! 上一篇文章<如何实现超时功能(以CompletableFuture为例)>中我们讨论了 ...
- redis安装、多实例和配置、及服务器性能优化
同一台服务器部署不同应用或者同一应用部署不同环境,需要redis服务多开防止数据冲突问题. 一.安装redis 需要安装gcc编译工具 yum install gcc -y 源码安装默认Redis程序 ...
- 4.vue Router路由设置
router=>index.js 设置路由信息 1.路由文件按分组拆分多个 import analysisRouter from './analysisRouter'; import users ...
- Doris建明细测试表,导入测试数据
分区.分桶.明细表 测试用户表 CREATE TABLE user_info( dt DATE, id varchar(36) NOT NULL DEFAULT '10', user_name var ...
- Luogu P11553 ROIR 2016 Day 1 奇怪的字符串 题解 [ 绿 ] [ 后缀自动机 ] [ 枚举 ] [ 观察 ]
奇怪的字符串:需要一点观察的 SAM 小清新题. 观察 我们首先观察什么样的字符串才是奇怪的,可以发现,首先类似 AAAAAAA 之类全部相等的字符串是奇怪的. 继续观察,如果字符种类变为两种或者三种 ...
- Linux驱动---LED
目录 一.pinctrl子系统 二.GPIO子系统 三.GPIO操作步骤 3.1.获取GPIO描述符 3.2.设置方向 3.3.读写值 四.编写LED驱动 4.1.硬件原理图 4.2.修改设备树 4. ...
- 泰山派linux(Ubuntu 20.04)安装GCC编译环境
linux(Ubuntu 20.04)安装gcc编译环境 1.查看可安装的编译链版本(在用户apt软件源中检索) apt-cache search aarch64 交给AI翻译 后面验证得知本版本Ub ...
- QT5笔记: 21. QStandardItemModel
QStandardItemModel 存放数据 QItemSelectionModel 选择项模型 例子:本例子中QListView 没有做任何处理,只是拖放至ui文件,设置了布局 mainwindo ...