技术分享连载(八十九)

简介:

内存

Q1:我写了一个用例加载AssetBundle,并将多个特效Prefab实例化到场景中。连续运行了多次用例并把添加的特效对象都删除,而且切换了场景,我看到Profiler中的内存变化如下图所示:
请输入图片描述
我想咨询下:
1. Profiler里的Reserverd Unity内存比Used Unity内存高出很多是正常的吗?
2. 如果正常的话,有办法可以回收Reserverd Unity内存吗?
3. Reserverd Unity内存在运行完多次上述的用例后稳定在400MB,再运行一次用例可以上涨到450MB,虽然后面会回落到400MB。这样的表现也是正常的吗?

  1. 题主这个数据是在Editor中做测试的结果吗?Reserverd比Used高出这么多确实不太合理;但如果是Editor中,那么Unity其实会做很多辅助操作,这些也确实是会占用内存的。所以,建议在真机中测试看看,看看这个差距是否会下来。但如果是在真机中,那么这个差距确实过高了,不太合理。

  2. Reserverd Unity的内存是引擎自身管理的,一般会在后续不使用时自己降下来。

  3. 这种升高和回落是正常的,但至于是否应该这么高,请见1中的回答。

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a1fde25bd7d86f726903207


内存

Q2:我想咨询下,Resources.UnloadUnusedAssets() 在卸载旧场景后加载新场景前调用好,还是在加载新场景后调用比较好呢?如果考虑内存峰值的话,我觉得是前者好,但是在UWA上看到有些文章说是加载场景后调用,所以想深入学习下。

如果题主是通过LoadLevel(Async)类似的方式来加载场景的话,那么Unity自身会在底层执行一次类似Resources.UnloadUnusedAssets的操作。所以,这时如果手动调用Resources.UnloadUnusedAssets操作,时间间隔很短,其实这个是有些重复的。因此,我们才建议在新场景加载后再调用一次。

但如果题主使用LoadLevelAdditive或其他类似的API来切换场景的话,那么Unity是不会调用Resources.UnloadUnusedAssets的,这时你再旧场景卸载后调用,其实也是很不错的选择。

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a1fc7dbbd7d86f726903206


渲染

Q3:是否可以认为Shader里 Blend Off和Blend One Zero是完全等价的?我在Unity的Standard Shader里看到它的混合是使用形如Blend [_SrcBlend] [_DstBlend]来动态控制,并且注意到其在StandardShaderGUI.cs里设置Opaque时就是设置的 Blend One Zero,那么是否可以认为在Shader里写Blend One Zero的话,和Blend Off是等价的?Unity会自动改变blendstate从而避免从destbuffer读取数据?

我们在Unity 2017.1上测试了一下,发现实际上在Android平台的GLES调用中,Unity的Standard Shader的Opaque模式是在disable blend的状态下渲染的,实验如下:

设备:红米2。渲染场景是两个Standard Shader Opaque模式物体(Sphere和Cube),中间有一个Unlit Transparent的Quad:
请输入图片描述
通过Android工具查看GLES API调用发现,每一帧渲染Cube和Sphere的时候Blend都是关闭状态(上一帧结束时关掉),然后在渲染Unlit Transparent的Quad时打开:
请输入图片描述
其中,36个顶点的DC是渲染Cube,2304个顶点的DC是渲染Sphere,6个顶点的 DC是渲染quad。所以看起来Standard Shader的Opaque模式应该是glDisable(GL_BLEND)的状态下渲染的。

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a1a8e710aef30913881b489


内存

Q4:在游戏每次打完副本回到主界面后,内存数据总是不太一致,其中通过Unity Profiler我观察到ManagedHeap.ReservedUnuseSize和ManagedHeap.UseSize的数值一直在变化,请问这个变化是否是合理的?

ReservedUnuseSize和ManagedHeap.UseSize一直在变化是正常的,它们都属于Mono内存,前者是当前Mono内存中没有使用的,后者是正在使用的。一般游戏中,Mono堆内存是会经常由代码来进行分配的,所以这两个值一直在变化,也是很正常的情况。

这里建议题主密切关注以下两点:
(1)Mono的总堆内存是否一直在升高
下图是UWA性能测评报告中的Mono堆内存走势图,其中的紫色线条即为项目运行时的ManagedHeap.UseSize,而黄色线条为ReservedUnuseSize,这两者都是在变化的,但最需要关心的是蓝色线条Reserved Mono,这条线条如果持续往上走,那么就说明项目中是很可能出现了内存泄露问题,需要研发团队彻查,建议通过Mono详细堆内存分析来进行修复。
请输入图片描述
(2)具体的堆内存分配是否合理
ManagedHeap.UseSize或者Mono总内存的上升都是由于代码的堆内存产生的,所以查看代码堆内存分配是否合理,避免不必要的堆内存分配是非常重要的,类似于下图。
请输入图片描述
建议题主参考以下两篇文章:

  • 用正确的方式,三天搞定Mono堆内存泄漏!
  • Unity游戏的代码堆内存优化






原文出处:侑虎科技
本文作者:admin
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。

目录
相关文章
|
图形学 Android开发 缓存
|
图形学 异构计算 编解码
|
iOS开发 图形学 Android开发
|
图形学 Android开发 分布式计算
|
API 图形学 iOS开发
|
图形学 iOS开发 异构计算
|
前端开发 图形学 数据可视化