《Unity3D高级编程 主程手记》第二章 C#技术要点(一) Unity3D中的C#的底层原理

  1. Mono 和 IL2CPP 有什么区别
  2.  又是如何运作的

基础名词:

IL:Intermediate Language,中间语言

CIL:Common Intermediate Language,特指在 .NET 平台下的IL标准。大部分情况下与 IL 表示的是同一个东西。

CLI:Common Language Infrastructure,通用语言架构

JIT:Just-in-time,动态编译

AOT:Ahead-of-Time,静态编译

两种机制:Mono、IL2CPP

        在Unity中使用C#最重要的好处是编译快且开发效率高。但是 .NET 只能运行在 Windows 上(现在 NetCore 可以实现多平台,只是还不够完善),微软没有考虑跨平台并且没有将其开源。

        后来微软向ECMA申请将C#作为一种标准(2003年成为标准)。这意味着只要遵守 CLI(Common Language Infrastructure)的第三方能用任何语言实现 .NET 平台。

Mono

        由Xamarin公司所主持的自由开放源代码项目。它基于 CLI 和 C#的 ECMA 标准,提供了微软 .NET 的另一种实现方式。

        目的:达成跨平台 .NET 4.0 的完整功能支持。

        编译:C#、VB、J#这些遵守CLI规范的高级语言,会被各自的编译器编译成中间语言 IL,当需要运行他们时就会被实时的加载到运行库中,由虚拟机动态地编译成汇编代码(JIT)并执行。

        在 Unity 中,Boo、 Unity Script 同样是被各自的编译器编译成 IL 后,再由 Mono 虚拟机解释并执行。

        IL 有三种转译模式:

  • JIT:在程序运行过程中将 CLI 转译成机器码。
  • AOT:将 IL 转译成机器码并存储在文件中,此文件不能完全独立运行。部分代码不能产生机器码,如 trampolines 或者控管监督相关代码 仍需要 JIT。
  • 完全静态编译:只支持少数平台,iOS、PlayStation 3、XBOX 360 等不允许使用 JIT 的平台。

        Unity 在打包 iOS 时使用第三种方式,在 Android 和 Windows 上使用第一种方式。

        三类组件:核心组件、Mono/Linux/GNOME 开发堆栈、微软兼容堆栈

  • 核心组件包含 C# 编译器、CLI 虚拟机,以及核心类别程序库。
  • Mono/Linux/GNOME 开发堆栈提供了工具用于开发应用软件。这些工具使用了既有的GNOME 以及自由且开放源代码的程序库,它们包含了针对图形用户界面开发的Gtk#、可套用 Gecko rendering engine 的 Mozilla 程序库、Unix 集成程序集(Mono Posix)、安全堆栈,以及 XML schema 语言 RelaxNG 。
  • 微软兼容堆栈提供了一种方式以使 Windows .NET 应用程序可以被移植到 GNU/Linux 上,堆栈包含了 ADO.NET、ASP.NET 以及 Windows Forms等。

        垃圾回收机制:使用Simple Generational GC(SGen-GC)作为默认的垃圾回收器。

        主要思想:将对象分为两个内存池,一个较新,一个较老,那些存活时间长的对象都会被转移到较老的内存池中去。

        C#生成的 IL 编码称为托管代码,由虚拟机执行和GC管理。C/C++ 或 C# 中以不安全类型写的代码称为非托管代码,虚拟机不能跟踪这类代码,需要手动管理。

        使用托管代码编写游戏逻辑非托管代码用于更底层的架构、第三方库或者操作系统相关接口。

IL2CPP

为什么加入 IL2CPP 机制?
  1. Mono 维护成本大,Unity 的 Mono 虚拟机有自己的修改方案,需要自己维护独有的虚拟机程序。每新增一个平台,Unity 的项目组就要把虚拟机移植一遍,同时解决问题。
  2. Mono 版本授权受限,Mono 版本无法升级,很多 C# 新特性无法使用。
  3. 提高运行效率,程序运行效率提升了 1.5~2.0 倍。
编译与运行过程

        首先由 Mono 将 C#  翻译成 IL,再将 IL 重新变回 C++ 代码,再有各个平台的 C++ 编译器直接编译成能运行的机器码。

        IL2CPP 有自己的虚拟机,该虚拟机不执行 JIT 或翻译代码,主要用于内存管理,其内存管理才有类似 Mono 的方式,程序员无需关心两者的内存差异。

        IL2CPP实现了另一种AOT完全静态编译。

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 09:02:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 09:02:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 09:02:01       58 阅读
  4. Python语言-面向对象

    2024-07-16 09:02:01       69 阅读

热门阅读

  1. ArcGIS Pro SDK (九)几何 4 折线

    2024-07-16 09:02:01       19 阅读
  2. 如何保护你的网络安全?

    2024-07-16 09:02:01       23 阅读
  3. 北京交通大学学报-社会科学版

    2024-07-16 09:02:01       21 阅读
  4. 【AI应用探讨】—生成对抗网络(GAN)应用场景

    2024-07-16 09:02:01       25 阅读
  5. QT教程-十四, QSpacerItem(可伸缩的空间项)

    2024-07-16 09:02:01       21 阅读
  6. 初学者指南:如何搭建和配置 Nginx 服务器

    2024-07-16 09:02:01       22 阅读
  7. Canvas

    2024-07-16 09:02:01       23 阅读
  8. 增加扫地机器人的智能化功能

    2024-07-16 09:02:01       24 阅读
  9. 网络爬虫Scrapy shell 的使用和介绍

    2024-07-16 09:02:01       26 阅读