跳转至

动态创建反射信息优化

主要内存占用都在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初始化时产生大量成员函数的反射信息。