近期项目即将上线,为了抗住数量众多的玩家,流畅的进行多人同屏对战,我们不得不对游戏进行一次彻底的优化。
这个系列就是我对于此次优化的一些总结吧。
首先优化是足够了解原理的基础上并且辅以相应的工具才能顺利进行,在优化GC里,我们用到了Unity自带的Profiler,这是一个非常优秀的工具,不仅仅支持编辑器下的调试,还可以看到在设备上的信息。
那么,为什么要进行GC优化呢?
因为GC积累到一定的量,Mono会自动回收内存,当自动回收的时候,会造成一定的卡顿,如果GC产生的速度非常快,这个过程就不断频繁的发生,就会导致游戏不停的卡顿。
关于GC优化,我认为有两个部分是GC优化的重点:
1.Update中的GC优化
2.频繁使用和销毁的GO的缓存池
最终的目的就是,我们希望尽可能的把Mono自动回收内存这个过程放到加载中做,游戏正常运行中尽量干掉这个玩意。
先说说Update中产生的GC,Update中的GC是非常重要的而且是可以完全避免的,很多说到优化的文章都会写到,如果Update中有10K的GC的话,每秒60帧,就有600K的GC,每分钟36M,这是一个非常恐怖的量级,所以0GC的Update是游戏稳定运行的核心。
再说说GC产生的原理,很简单:向堆里申请内存
无论是通过哪种途径产生的GC,原理都是向堆里申请内存。
另外GC的产生方式有下面几种:
1. New Class ,注意 结构体New出来是不产生GC的,因为结构体存在栈中
2. 装箱拆箱
3. 字符串操作
4. 匿名函数(匿名函数本身并不会造成GC,但是一旦用到了闭包,也就是在匿名函数中使用了栈中的变量,C#就会自动将栈中的变量拷贝到堆里面,进而实现闭包,具体我会在后面单独写一篇例子分析这个现象。)
值得注意的一点就是,Unity为了让用户调试更加方便,或者是基于跨平台的目的,在Editor中产生的GC可能在设备上并不会产生,所以真正要验证是否存在GC或者是否消灭了GC,必须要到设备上验证。