Unity-GC优化相关笔记
Unity官网GC定义如下
创建对象、字符串或数组时,用于存储它的内存是从称为堆的中央池分配的。当此项不再使用时,其先前占用的内存可被回收并用于其他目的。在过去,通常由程序员通过适当的函数调用显式地分配和释放这些堆内存块。如今,Unity 的 Mono 引擎等运行时系统会自动为您管理内存。自动内存管理比显式分配/释放的做法需要更少的编码工作,并且大大降低了内存泄漏的可能性(即分配了内存但后续从未释放的情况)
简单来说,GC会在单帧【非增量式】中,遍历堆上对象,清理掉受Unity完整托管的已被标记为无用内存的内容,是一种行为。而优化gc则指的是如何加速这次回收操作,以防止玩家突然在某一帧感觉卡顿。
【这里着重强调托管是因为踩过一个坑,Texture2D是部分托管的类,新建一张Texture2D,并用Sprite.Create挂到一张image2d上,后面如果这个image换了别的Texture 原本的Texture是不会被释放的,这会导致内存泄漏】
GC的时机
- 定时GC
- 手动强制GC
- 内存不够时启动GC获得额外内存
Profiler窗口可以定位是否是GC导致的性能热点
优化方法
首先,栈上内存是直接释放的,不走GC
- struct中不添加引用类型变量,会导致GC监控该类型的对象,添加开销
- 减少装箱
减少引用对象的创建与摧毁
- 对象池管理
- 减少Update等大量调用函数中,申请内存的逻辑
杂项
- 字符串操作使用stringbuilder
- for代替foreach
- 在合适的时机手动GC
参考
https://blog.unity.com/cn/games/optimize-your-mobile-game-performance-tips-on-profiling-memory-and-code-architecture-from
https://www.cnblogs.com/hearthstone/p/13357925.html
https://www.cnblogs.com/zblade/p/6445578.html