【Unity优化】内存优化
IL2CPP 与 Mono
1)IL2CPP 优缺点
① 可以调试C++代码
② 可以使用 Engine code stripping 减少代码大小
③ 编译慢
④ 只支持 AOT(Ahead of Time)
2)Mono优缺点
① 编译快
② 支持JIT(Just In Time compilation)
3)现状
① WebGL 和 UWP 只支持 IL2CPP
② iOS 因为要支持64位,需要用 IL2CPP
代码剔除
1)代码大小,直接影响硬盘和运行时内存空间占用。
2)托管代码剔除
① Unity 在方法层级剔除托管代码
② 可通过 Player Setting → Other Settings → Stripping Level,更改剔除层级
③ UnityLinker 从IL中剔除未使用的类型(class、structs等);如果类型被使用,还要剔除未使用的方法
④ 使用 Mono 时,是否剔除是可选的;使用 IL2CPP 时,强制开启剔除
3)原生(本地/引擎)代码剔除
① 通过 Player Setting → Strip Engine Code 开启引擎代码剔除
② 仅支持 iOS、WebGL、Android 平台
4)Unity模块剔除:仅 WebGL 支持
5)C# 代码剔除
① UnityLinker 使用“标记 → 剔除“原则,和垃圾回收类似。
② UnityLinker 将一些类型和方法标记为 root,然后遍历他们的所有依赖关系。
③ 场景中,或 Resources 资源中用到的类,被标记为 root。
④ user assemblies 中的所有类型和方法,也被标记为 root。
⑤ 如果场景或某个资源,用到了其他程序集,则这些程序集也被标记为 root。
⑥ 还可以通过编辑 link.xml 文件,将其他类型或方法标记为 root。
⑦ 对于AB,使用 BuildPlayerOption.assetBundleManifestPath 标记额外的类型或方法标记为 root。
⑧ 将未使用的代码编译为程序集,方便剔除。
6)泛型共享
① IL2CPP 支持共享引用类型的泛型实现,减少代码占用空间。
② IL2CPP 不支持共享值类型泛型,应减少使用
引擎代码内存占用细节
1)引擎代码大部分是常驻内存的,且通常无法控制和优化。
2)Unity使用不同的 allocator 和 buffer,有些是常驻的,有些是动态的。
3)Unity使用一个4MB大小的buffer pool存储常量,每帧循环遍历。该pool与GPU绑定
4)block allocator:分配一个新的块内存页,会产生内存和CPU负荷。通常Unity第一次使用某个系统,分配的块内存是够用的。分配完后重复利用。
5)AssetBundles:第一次加载AB时,需要 block allocator,然后复用。但是如果想要同时加载多个AB,则相应需要多个 block。
6)Resources:与其他系统共用 block allocator,在启动时就已分配,因此加载资源时没有相关负荷
7)Ringbuffer:Unity使用它推送纹理给GPU,通过 Quality.asyncUploadBufferSize 设置 ringbuffer 大小。
Assets
原生占用内存不被需要时,能够被返回给操作系统。
一些减少 Assets 原生内存占用的方法:
① 移除 mesh 中不需要的 channel
② 移除动画中的重复关键帧
③ 使用 Quality Settings → maxLOD,在打包时移除高细节网格
④ 打包后,检查 Editor.log 文件,每个资源的内存占用是否正常
⑤ 使用 Quality Settings → Rendering → Texture Quality,通过 mipmap 强制降低纹理分辨率,减少向GPU传输的内存占用
⑥ 法线贴图不需要和漫反射贴图一样大,使用低一些的分辨率不会影响质量。
9)材质克隆:使用材质的属性将克隆返回一个新的材质;使用 shaderdMaterial 替代。
10)卸载场景:只卸载了GO,没有卸载资源,需要使用 UnloadUnusedAssets 卸载。
音频
1)Virtual Voices:Unity中远而小的音频使用 virtual;近而大的使用 real(不懂)
2)DSP Buffer Size:该设置影响延迟
3)音频导入设置
① 如果不需要立体声,开启 Force to mono 选项,减少内存占用。
② 大段音频应该使用 Streaming,占用200KB内存,因此200KB以下使用 Compressed;缺点是有一点延迟。
③ 长音频如果没有设置为 Steaming,可以设置为 Compressed,减少运行时内存。
④ 如果内存宽裕,使用 Decompress,提升CPU性能
4)音频压缩格式(Compression Format)选择
① 非常短的音频:设置为 ADPCM,压缩比为3.5:1,解压负荷低
② 安卓上的长音频:使用 Vorbis;Unity不支持硬件加速解码
③ iOS上的长音频:使用 MP3 或 Vorbis
④ MP3 和 Vorbis 格式有一定解压负荷,但是文件小。
⑤ MP3越高清,解压负荷越小;中小清晰度的CPU负荷差不多。
⑥ 循环的音频:推荐使用 Vorbis。MP3格式循环式可能会有短暂静音(因为需要前置大小的数据块,如果循环不是块大小的整数倍,则会静音等待)