【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格式循环式可能会有短暂静音(因为需要前置大小的数据块,如果循环不是块大小的整数倍,则会静音等待)

posted @ 2020-07-21 22:43  何三思  阅读(1420)  评论(0编辑  收藏  举报