1、Unity是一个C++引擎
Unity是一个C++引擎,并不是C#引擎,底层代码全部是由c++写的,除了一些Editor里面的Services可能会用到NodeJS这些网络的语言,Runtime里面用到的每一行Unity底层代码全是C++的。
Unity实际上分为三层:
- 最底层是我们的Runtime,全是Native C++代码。
- 最上层是我们的C#,Unity自己有一些C#,例如Unity的Editor是用C#写的,还有些Package也是C#写的。
- 中间还有一层我们叫Binding,可以看见很多的.bindings.cs文件(基于C#的binding语言,一开始是Unity自定义的一种语言),这些文件的作用就是把C++和C#联系在一起,为我的C#层提供所有的API。
因此我们平时使用Unity时看见的C# API,都是在Binding层中自定义的。这些文件底层运行的时候还是C++,只是个Wrapper(封装)。
最早我们的用户代码是运行在C#上,是MonoRuntime。但是现在可以通过IL2CPP将其转成C++代码,所有现在几乎没有纯正的C#在运行了。
Unity的VM(虚拟机:Virtual Machine)依旧还是存在,主要用于跨平台,有了一层VM抽象后,跨平台的工作会容易很多,IL2CPP本身也是个VM。
2、内存管理简介
Unity内存按照分配方式分为:Native Memory(原生内存)和Managed Memory(托管内存)。Native Memory并不会被系统自动管理,需要我们手动去释放。而Managed Memory的内存管理是自动的,会通过GC来释放。
此外Unity在Editor和Runtime下,内存的管理方式是不同的,除了内存大小不同,内存的分配时机以及分配方式也可能不同。
例如Asset,在Runtime时,只有我们Load的时候才会进内存。而Editor模式下,只要打开Unity就会进内存(所以打开很慢)。因此后续有推出Asset Pipeline 2.0,它会一开始导入一些基本的Asset,剩下的Asset只有你使用的时候才会导入。
Unity按照内存管理方式分为:引擎管理内存和用户管理内存。引擎管理内存即引擎运行的时候自己要分配一些内存,例如很多的Manager和Singleton,这些内存开发者一般是碰触不到的。用户管理内存也就是我们开发者开发时使用到的内存,需要我们重点注意。
3、Untiy检测不到的内存
Untiy检测不到的内存即Unity Profilter无法检查到的内存,例如用户分配的Native内存。比如自己写的Native插件(C++插件)导入Unity,这部分Unity是检测不到的,因为Unity没法分析已编译的C++是如何分配和使用内存的。还有就是Lua,它完全自己管理的,Unity也没法统计到它内部的情况。