Unity的内存管理
Unity由两部分内存来组成,原生内存(Native Memory)和托管内存(Managed Memory)。
其中 Native Memory 是引擎管理的内存,大家接触的会比较少,而且可操控性也比较少。例如资源文件,如:纹理贴图,模型网格,音频,动画等;以及引擎内部模块,如:渲染模块,粒子模块,物理模块等,这些所占的内存,就由Unity自身来进行管理的。
我们平时开发通常会接触到的是 Managed Memory,也就是我们自己定义的各种类,如果这部分内存爆了,就需要我们自己去进行优化。
需要注意的是,Managed Memory 包括了用户使用的 值类型(Value Type)值和引用类型(Reference Type) 对象 所占用的内存,通常情况下,值类型 分配在栈上,引用类型分配在堆上,栈上保存的只是一个引用地址,这其中只有 引用类型 的部分需要 Garbage Collection 进行管理。
Unity的垃圾回收机制
垃圾回收的好处:系统会自动回收,无需手动回收。避免内存泄漏导致程序崩溃。
Unity 使用的GC是贝姆垃圾收集器(Boehm-Demers-Weiser Garbage Collector),是一种保守式回收器。Boehm回收有两个特点,一是不分代和不合并的,所以可能会导致内存碎片。二是所有保守式内存回收都是非精准式内存回收。何为非精准?常规理解是我分配出去的内存你可能收不回来。实际上还有另一层意思:你没分配的内存你可能也用不了。也就是说,一是我已经分配出去的内存在没有人在引用它的情况下,不一定能收得回来。二是我没有分配使用的内存,当你想去分配使用的时候也不一定用的了。(参考 【笔记】Unity内存分配和回收的底层原理 - 知乎 (zhihu.com )
即存在以下问题。
非分代式(Non-Generational)
非压缩式(Non-Compact)
碎片化(Fragmentation)
说回到性能优化,垃圾回收被触发时,所有程序代码暂停直到垃圾回收完成,有可能导致卡顿的发生。在 Profiler 上的表现如下图所示(棕色的对应尖峰上的棕色区域,GC尖峰(GC Spike)):
针对这个问题,我们可以通过开启 增量式垃圾回收(Incremental GC)解决。增量式垃圾回收 把原先一次性扫描和回收的过程分配到了多个帧里面,从而减少或者消除卡顿现象。当然,垃圾回收还是使用 BoehmGC(所以总的垃圾回收所需时长与原来的差不多)。
如下图所示,这些代表GC的棕色区域分布到了多个帧里面,回收之后内存占用就下降了:
若要开启 Incremental GC,打开 Edit > Project Settings > Player > Other Settings 界面, 选择 .NET 4.x 以及勾选 Use incremental GC 选项即可。
其它GC相关技巧
1. Debug.Log() 会消耗很多性能,正式发布时注意精简日志。
2. 缓存经常用到的组件(Component)。
3. 使用对象池(Object Pooling)。
标签:垃圾,Garbage,回收,Unity,GC,Collection,Memory,内存 From: https://www.cnblogs.com/bakabird/p/U3DProfiler_3_GC.html