[搬运工]移动游戏加载性能和内存管理全解析

UWA 六月直播季 | 6.8 移动游戏加载性能和内存管理全解析

https://blog.uwa4d.com/archives/livebroadcast6-8.html

因为这篇文章没有提供PPT供参考 所以写这一篇文章来记录一下1个多小时的视频中讲解的哪些优化点,

文章中的图片都是UWA收集的

 

UWA优化法则之一

如果你不能"定位"它,就没办法"优化"它

"If you cannot measure it you cannot improve it." ---Lord Keivin

 

加载模块

  • 核心问题
  1. 加载耗时瓶颈
  2. AssetBundle加载/卸载是否合理?
  3. 资源加载/卸载是否合理?
  4. 实例化操作是否合理?
  5. 资源冗余怎么办?

加载耗时瓶颈 

函数名称:

  • Loading.UpdatePreloading
    • GarbageCollectAssetsProfile 资源卸载
    • Loading.AwakeFromLoad 资源加载
      • LoadingReadObject
      • Texture.AwakeFromLoad
      • Shader.Parse
    • Application.LoadLevelAsync Integrate GC耗时
      • GC.Collect
    • UnloadScene GameObject 销毁

自定义逻辑代码

  • AssetBundle和资源加载\实例化\动态合批等
    • Loading.ReadObject
    • Loading.LockPresistentManager
    • Loading.LoadFileHeaders
    • AssetBundle.LoadAssetAsync 

更为具体的加载耗时

  • Resource.Load加载
  • AssetBundle.Load加载
  •  LoadFromeFile加载(推荐)

 如何去优化

合理使用资源

  • 纹理资源
    • 纹理格式
    • 分辨率
    • Mipmap

[搬运工]移动游戏加载性能和内存管理全解析_第1张图片

Unity加载模块深度解析(纹理篇)

 https://blog.uwa4d.com/archives/LoadingPerformance_Texture.html

  • 网格资源
    • 顶点数
    • 顶点属性
    • Read/Write

[搬运工]移动游戏加载性能和内存管理全解析_第2张图片

Unity加载模块深度解析(网格篇)

https://blog.uwa4d.com/archives/LoadingPerformance_Mesh.html

  • 动画资源
    • 压缩格式
    • 数据精度
    • 动画类型

[搬运工]移动游戏加载性能和内存管理全解析_第3张图片

Unity加载模块深度解析之动画资源

https://blog.uwa4d.com/archives/Loading_AnimationClip.html

动画资源:4000帧,133s,58根骨骼

降低精度

[搬运工]移动游戏加载性能和内存管理全解析_第4张图片

KeyFrame-Opt降低数据精度,从8位减至3位

[搬运工]移动游戏加载性能和内存管理全解析_第5张图片

[搬运工]移动游戏加载性能和内存管理全解析_第6张图片

动画类型

Generic

Humanoid(建议) 性能提升,降低AnimationClip数量,降低使用的种类

[搬运工]移动游戏加载性能和内存管理全解析_第7张图片

 

  • Shader
    • KeyWord 数量

[搬运工]移动游戏加载性能和内存管理全解析_第8张图片

Unity加载模块深度解析(Shader篇)

https://blog.uwa4d.com/archives/LoadingPerformance_Shader.html

Keyword的降低确实可以大幅降低Shader的解析时间,进而提升加载效率。

  • 音频资源
    • 包体大小 在音质允许的情况下首推MP3格式
    • 内存大小 双通道,加载类型
      • LoadType 加载类型
        • Decompress On Load 加载时解压,然后以非压缩的形式放在内存中
        • Compressed In Memory 保留压缩格式在内存,使用时解压
        • Streaming 在本地以文件流的形式读入解压播放(此方法使用最少量的内存来缓冲从磁盘中逐步读取并在运行中解码的压缩数据)
      • Compression Format 压缩格式
        • PCM (高清格式)
        • Vorbis(OGG)
        • ADPCM(轻度压缩的高清格式)
        • MP3(Android)
    • 加载效率
      • Compressed + Vorbis   1.0x
      • 其他格式 + Vorbis
        • 4.0x(不开启Load In Background )
        • 1.0x(开启Load In Background)
      • 所有格式 + PCM
        • 9.0x(不开启Load In Background )
        • 5.0x(开启Load In Background )
    • 运行压力
      • Decompress On Load(低)
      • Compressed In Memory(中)
      • Streaming (高)

占用内存空间图

Streaming  <<  Compressed + Vorbis  <<  其他设置 

[搬运工]移动游戏加载性能和内存管理全解析_第9张图片

Vorbis的Quality可以进一步控制,建议50%(个人使用1%效果还行)

音频资源加载效率

1.0x 一倍数   n.0x n倍数

[搬运工]移动游戏加载性能和内存管理全解析_第10张图片

不急于播放的音频,可以开启Load In Background来提高加载性能,比如背景音乐 

需要实时播放的音频,比如开枪,走路,打击就不要开启了

运行时CPU消耗

[搬运工]移动游戏加载性能和内存管理全解析_第11张图片

[搬运工]移动游戏加载性能和内存管理全解析_第12张图片内存占用最小的 CPU消耗最大

总结一下:

  • 合理使用资源
    • 音频资源
      • 建议使用mp3格式的音频文件
      • 如果内存压力过大,则可以考虑Streaming加载方式或较小Qulity质量的Vorbis格式
      • 如果是非及时使用音效,建议开启Load In Background来提升加载效率
      • 如果存在大量频繁使用音效,建议选择Decompressed On Load来降低CPU开销
      • 自己压缩,建议采用 Gzip+LoadFromFile(Async)

 Unity官网链接

https://docs.unity3d.com/Manual/class-AudioClip.html

 

粒子系统

粒子系统经常使用,也经常疏忽

粒子系统加载Material耗时非常大,单独加载多个粒子耗时会翻倍

建议一个AssetBundle包中保存多个粒子,一次性加载多个粒子的耗时增加相对来说少很多

  • 粒子系统优化
    • 材质剥离
    • 数量  

[搬运工]移动游戏加载性能和内存管理全解析_第13张图片

如何优化

  • 更完善的加载/卸载管理
    • AssetBundle加载
      • 加载方式
        • new WWW
        • LoadFromCacheOrDownload
        • LoadFromFile
      • 优化方式
        • unity5.3版本以后,建议将AB直接以LZ4格式进行发布
        • 如果本地加载,建议使用LoadFromFile(Async)来加载
        • 根据机型的不同,选择合适的Coroutine次数
      • 加载频率
      • 驻留情况(不要卸载后立马加载)
      • 加载错误(不要加载不存在的文件)
      • 特例缓存(缓存加载时间过长的资源)

测试实验数据 AssetBundle压缩格式 

[搬运工]移动游戏加载性能和内存管理全解析_第14张图片 

测试加载方式: 红米Note2

测试结果:ETC1 ,测试100次取平均值

[搬运工]移动游戏加载性能和内存管理全解析_第15张图片

LoadFromCacheOrDownload为什么LZMA很快(因为第一次加载后缓存了)

测试结果:RGB24 ,测试100次取平均值

[搬运工]移动游戏加载性能和内存管理全解析_第16张图片

测试结果

[搬运工]移动游戏加载性能和内存管理全解析_第17张图片

AssetBundle加载问题-Coroutine次数

[搬运工]移动游戏加载性能和内存管理全解析_第18张图片

[搬运工]移动游戏加载性能和内存管理全解析_第19张图片

因为每加载完一个AssetBundle后就yield return跳过当前帧

导致加载小的零碎资源包时CPU没有跑满,也就导致了加载总时间过长

AssetBundle打包

自己压缩,建议采用 Gzip+LoadFromFile(Async)

压缩比例图 

[搬运工]移动游戏加载性能和内存管理全解析_第20张图片

解压时间图

[搬运工]移动游戏加载性能和内存管理全解析_第21张图片

压缩时间图

[搬运工]移动游戏加载性能和内存管理全解析_第22张图片

以上是AssetBundle的说明和加载解压方式的比较

加载频率,驻留情况

[搬运工]移动游戏加载性能和内存管理全解析_第23张图片

从上图我们可以发现问题,这个资源被加载和卸载了很多次

但是内存驻留的情况却是一直常驻

这是因为每次卸载资源后立刻加载了资源,导致了性能上的浪费

同步异步加载时间对比

AssetBundle.Load   VS AssetBundle.LoadAsync

[搬运工]移动游戏加载性能和内存管理全解析_第24张图片

[搬运工]移动游戏加载性能和内存管理全解析_第25张图片

LoadALL   VS   Load OneByOne

[搬运工]移动游戏加载性能和内存管理全解析_第26张图片

做一个特殊的测试

使用10张相同的 ETC1格式 1024*1024分辨率 LZ4压缩格式 在 红米Note2上测试加载效率

[搬运工]移动游戏加载性能和内存管理全解析_第27张图片

AssetBundle资源加载小结

  • 切换场景时,尽可能使用AssetBundle.load来提升加载效率
  • 尽可能使用LoadAll来加载资源
    • 保证同时使用的资源打包在一起
    • 小,细碎的同类资源打包在一起(Shader,ParticleSystem)

 

Instantiate实例化操作

优化实例化次数,添加缓存池

如何优化:

  • 将频繁Instantiate/Destroy的GameObject放入缓存池
  • 将部分耗时资源进行预加载

Active/Deactive操作

Active/Deactive频率和耗时

大部分情况下Active/Deactive比Instantiate/Detroy要好

有两类GameObject建议不要频繁切换

  • 复杂的UI界面
  • 带动画组件的GameObject(每次设置Active会调用动画组件的初始化)

建议把不想显示的GameObject移动到视野外面去,并把Component给disabled 掉,等需要的时候移回视野内并enabled

这样就没有重建的CPU开销

 

UWA优化法则之二

勿以恶小而为之,勿以善小而不为             ---刘备

内存管理

  • 内存使用是否合适

  • 内存泄漏如何解决

统计市面上MMO游戏和ARPG游戏的资源分布图

纹理资源:(建议不要大于150MB)

 [搬运工]移动游戏加载性能和内存管理全解析_第28张图片

纹理资源如何优化?(UWA mipmap工具 可以给纹理分辨率建议)

[搬运工]移动游戏加载性能和内存管理全解析_第29张图片

网格资源 (建议缩减到20mb以下)

[搬运工]移动游戏加载性能和内存管理全解析_第30张图片

优化Tangents数量

[搬运工]移动游戏加载性能和内存管理全解析_第31张图片

[搬运工]移动游戏加载性能和内存管理全解析_第32张图片

动画资源 

优化方式上文讲解了 减少动画精度,设置动画模式

[搬运工]移动游戏加载性能和内存管理全解析_第33张图片

[搬运工]移动游戏加载性能和内存管理全解析_第34张图片

音频资源 (建议小于15MB)

[搬运工]移动游戏加载性能和内存管理全解析_第35张图片

RenderTexture

  • 控制分辨率(截屏的时候改变分辨率,使用完成后把分辨率改回来)
  • 关注Antialiasing(抗锯齿)

[搬运工]移动游戏加载性能和内存管理全解析_第36张图片

[搬运工]移动游戏加载性能和内存管理全解析_第37张图片

粒子系统

提高粒子系统利用率

[搬运工]移动游戏加载性能和内存管理全解析_第38张图片

[搬运工]移动游戏加载性能和内存管理全解析_第39张图片

资源冗余

不同的AssetBundle包包含相同的资源

[搬运工]移动游戏加载性能和内存管理全解析_第40张图片

如何做到零冗余?

Unity 5.x AssetBundle零冗余解决方案

https://blog.uwa4d.com/archives/1577.html

AssetBundle(SerializedFile)

-数量尽可能保持在60以下(特别是Android平台)

5.6以前不论多小的AB都占有0.5MB的内存空间,5.6以后降低至16KB

 

关注总量分配(1w帧<30/50MB)

UGUI建议1w帧分配内存小于30MB

NGUI建议1w帧分配内存小于50MB

关注一次性分配(1MB以上)

关注谁在分配

  • 配置表解析(一般占用60~80%的内存)
  • new class
  • string 操作
  • Instantiate
  • 格式转换

内存泄漏

泄漏和缓存仅是一线之隔

  • Asset
  • AseetBundle
  • GameObject
  • 逻辑变量

每1000帧获取准确的驻留堆内存和变量数

查找堆内存增量:

5.4 UWA直播回顾:Unity游戏的代码堆内存优化

https://blog.uwa4d.com/archives/1766.html

平均三天即可大幅改善堆内存泄漏问题

UWA优化法则之三

空杯心态,用数据说话,一切经验归零

人之所以言之凿凿

是因为知道的太少

                    ---弗郎索瓦·基佐 

你可能感兴趣的:(Unity,优化,UWA)