动态创建反射信息优化¶
主要内存占用都在MethodInfo的创建和填充上
如何优化?¶
- 减小代码段和数据段大小
- 减小lib文件和globa-metadata.dat大小
- 减少动态反射信息
方向¶
- 代码裁剪(unity和il2cpp目前也有这个功能)
- 泛型优化(泛型共享,)
- 减少反射信息生成
IL2CPP基础结构¶
- Unity Class:所有class都继承自IlCppObject。64位一个空的class占用16字节,在il2cpp的实现中,class也只有一个基类,没有使用虚函数。GCAlloc尾部还有1Byte
- struct:就是c++中的普通struct。但是需要转换为object时,需要new一个structSize+IlCppObject大小的对象。
- 有利于Cache预取,对CPU更好
- 纯数据的结构,可以降低GC负担
泛型优化¶
当引用类型过多,泛型编译时会创建出过多的拷贝
+ 泛型共享:使用static可以共享一段通用的代码实现,以减少生成的代码大小
+ 泛型优化:但主要内存增加还是因为MethodInfo,反射信息动态填充产生的内存增量两者并不大
+ List<T>
替换成T[]
,因为List里有大量的函数和泛型衍生
+ ObjPool成员函数拆到一个静态类,生成1份反射数据
+ 最后将T[]
替换成object[]
,内存降低16M。不过T[]
本身也是一个大泛型类,所以替换了效果就更好了
C#容器优化¶
- List按2的幂次扩容是个非常差的选择,因为它通常正好是某一档的内存分配大小,例如List扩容到1024时,GC会进行一次1024 * 4 + 32or16 + 1的内存分配,刚好超4K大小,所以分配了8K内存,其中4K属于被浪费的
- 其次对List的扩容逻辑做了优化,提高其内存利用率,用真2的幂次打倒假2的幂次
- List的接口函数都放到了一个静态类ListUtil中,这样就能减少MyList初始化时产生大量成员函数的反射信息。