IL2CPP的运行时,作为脚本代码运行的虚拟机,它本身也会较多的内存消耗。这些内存主要用来保存脚本代码运行时元数据来加速脚本运行。 脚本元数据大小和工程的代码量是正相关的,一个直观反映就是global-metadata.dat文件的大小。 以一个14MB大的global-metadata.dat文件为例,在游戏运行时,IL2CPP运行时的内存消耗就达到了64MB,优化后内存降低到33MB。
在之前的实现中,IL2CPP在使用到某个类型时,会初始化这个类型完整的元数据,包括它的所有函数、接口、事件、属性、虚函数表等, 并且一旦加载后就不会再释放。 但分析发现,脚本代码实际运行时,通常只会用到很少的一部分元数据(反射、或者虚函数调用时访问)。 例如:一个数组类型有155个方法,25个虚函数,实现了6个接口,但实际运行时只会用到其中的很小一部分,存在冗余加载的情况。 因此延迟加载这些元数据,等到真正需要某个元数据项目时才去初始化这份数据可以显著降低内存占用。