使用UWA GOT优化Unity性能和内存

发表于2018-01-31
评论2 6.1k浏览

本文首发于知乎专栏:MACK的游戏开发笔记,欢迎各位关注。

使用UWA测试平台作为性能分析的辅助手段已经有很长时间了,每个版本测试一下可以得到一份整理过的报告,比人工分析高效不少。但毕竟网站提交的方式需要等一段时间,测试内容重点也难以定制,第一手数据结果也无法得到,还是有些不方便。这次得知UWA还出了本地化的工具,立马尝试了一下,果然非常给力。

GOT有三种分析方式CPU Overview,Mono Analysis和Assets Tracker,我最喜欢的是Mono Analysis,查找内存泄漏问题就方便很多。虽然分析上不如XCode全面详细,但已经满足日常的基本需求,一些测试工作也可以交由测试同学完成,离线分析。

UWA是基于Unity的Profile,使用方式就不多说了,官方的帮助文档非常详细。

以下是性能分析工具的上报截图:(日志文件在Client\TestData目录)



  • CPU Overview模式可以检测出高耗时的逻辑函数。在下图中,我们可以看到逻辑层的开销比较高,考虑到是帧同步,所有逻辑都在逻辑层,66ms更新一次,开销比较高的模块在角色,技能,网络等。由于在此之前,已经优化过几轮,各个模块的开销都比较平均了,没有明显的瓶颈,进一步的优化需要更细致的深度分析和优化了,属于打磨的过程。

  • Asset Tracker模式可以追踪到各个资源的使用情况,包括具体资源的格式是否合理,是否存在冗余等问题。下图可以看到AI的内存开销比较高。主要是因为AI对一些帧操作做了Clone。
  • 下图是日志和录像的系统开销,可以看到其耗时较高。不过录像系统只有Debug在客户端,Release版会记录在服务器,日志系统只有Debug版会记录本地,Release版只会上报不同步的、前后有限帧的数据,并且日志系统也将会改成记录二进制数据。
  • 下图是利用Asset Tracker功能发现的冗余MeshCollider,我们项目目前只使用了BoxCollider和基本的射线检测,在此基础上实现了一套简单的物理系统。因此是不应该有MeshCollider的使用,此处初判是误传的资源。
  • 特效和场景资源占用较高,还需要美术进一步优化。战斗激烈的时候特效占的内存甚至要比贴图和Mesh加起来还大。
  • 特效部分主要是粒子系统,使用次数非常多,产生的内存占用也相当高,超过了贴图的大小。这是因为射击游戏时,每帧会产生大量子弹,更需要小心使用和优化。
  • 场景的Mesh资源合并后,内存占用也比较高,因为场景一直无法确定,美术不能做人工静态合并,只能做载入时的静态合并,等场景确定下来可进行人工或借助插件合并。


  • FMOD的参数使用了String,并且调用次数非常高,导致GC较高,可以优化。

  • 下图是技能系统底层,我写的计时器使用了delegate,并且次数非常高,从而也导致了GC较高。因为整个游戏中,几乎所有的美术效果都使用这套系统,所以这块是目前最大的瓶颈。
  • 作为一个射击游戏,子弹数据非常高,虽然使用了内存池,也做了预加载并制定了一次策略,但是不同技能表现出脚本调用的频率差距很大,个别脚本预加载的个数远远不够。
  • UI的一些合并产生了较高的GC,可以划分动态和静态层,也可以对动态需要隐藏的UI使用移除屏幕等方式减少合并次数。
  • 下图为一些粒子系统播放开关产生的开销。
  • 跳字GC较高,因为使用了渐变,这部分可以做优化。
  • UWA GOT中的Mono Analysis可以对比两帧的内存快照,从而找到增量的部分。下图是实测图,对比两帧之间,可以发现还有一点创建角色的GC开销,看起来不高,我推测有角色漏了预加载,因为技能可能召唤角色,各种生成器会随机产生道具和怪物等,都有可能漏掉。此外开始帧和结束帧之间内存分配差异较小,说明优化得较好。
  • 针对FMOD Studio的GC问题,下图可以看到FMOD的字符串拼接开销非常高

查看源码可以看到FMOD插件代码写的有问题,大量使用了字符串拼接。

我们修改了FMOD的源码对路径进行了缓存降低的GC开销。


针对以上的分析结果一一指定了优化方案,性能也有了进一步的提升,特别是GC的开销大幅降低,降低了卡顿的几率。优化是一个漫长并且需要持续投入的工作,虽然不能直接被看到但对游戏品质也有巨大的影响。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引