技术分享连载(四)

技术分享连载(四)

上周的技术专题内存篇分享中,我们提到了内存泄露、Mono无效堆内存开销和资源冗余这三个常见“优化杀手”,今天我们再挑选几个开发者常常疑惑的问题,结合实例,加深大家的理解。


内存管理

Q1:System.ExecutableAndDlls占内存巨大,且一直在增长,这个属于正常情况吗?

System.ExecutableAndDlls该项显示的是执行文件和所调用的库(物理、渲染、IO等系统库)的总和。开发团队不用太担心该选项的数值,因为很多应用均在共用这些库,并且它对于真实项目的内存压力非常小,几乎没有影响,而且OS也不会因为该内存而杀掉游戏或应用。


内存管理

Q2:已经预加载怪物,然后显示怪物 PSS上升,并且在隐藏怪物后并没有下降,这是什么原因导致?显存上去了吗?

仅仅隐藏怪物的话,内存是不会下降的。因为隐藏只是改变了GameObject的状态,并没有对内存中的Object和资源进行移除。同时,即使是提前加载了怪物,也依然可能存在以上问题,因为某些资源是在显示的时候,才会传输一份到GPU的,比如Mesh。一般情况下,显存都不会即刻降低,这个是由Graphics Driver来管理的。建议可以看Profiler是否增长,如果Profiler没有问题而PSS持续增长,就有可能发生了内存泄露。

对于这个问题,建议查看性能优化,进无止境---内存篇(下)加深理解。


内存管理

Q3:我们在美术制作时做了40根骨骼,但在动作中仅用到了其中的30根。这种做法和30根骨骼用到了30根相比,在蒙皮计算上会明显增加吗?(Animation经过了压缩处理)

理论上是有增加的,骨骼运算均是每个骨骼阶段的Matrix乘起来的,所以理论上会有开销。建议使用Optimize GameObejct选项,可以减少一些不必要的CPU开销。


资源管理

Q4:Unity对Dynamic Batching的数量是否有限制?或者说对Saved by Batch的数量是否有限制?

Unity对于任何Mesh的面片都有65536的个数限制,拼合后的面片数也是如此。


内存管理

Q5:不太明白Profiler中ManagedHeap.UsedSize是什么,以及这个参数的意义何在?是否重要?

ManagedHeap.UsedSize是项目逻辑代码在运行时申请的堆内存,该选项只能通过优化代码来进行降低。 优化方法一般如下:

  • 尽可能地复用变量,减少new的次数;
  • 使用StringBuilder代替String连接,使用for代替foreach;
  • 对于局部变量或非常驻变量,尽可能使用Struct来代替Class。

ManagedHeap.UsedSize过大,一方面可能会影响一次GC的耗时;另一方面也可能反映出脚本中不合理的GC Alloc。


【技术小札】是UWA推出的技术交流栏目,我们会将开发团队中反馈的常见问题加以总结并梳理在此,以供大家参考。同时如果你也是个热爱分享、愿与大家抱团进步的程序员,欢迎加入UWA的QQ群(793972859),与我们奇文分享,疑义相析。