升级Unity后产生的Objects内存泄露现象

升级Unity后产生的Objects内存泄露现象

1)升级Unity后产生的Objects内存泄露现象
2)能否使用OnDemandRendering API来显示帧率
3)Unity闪退问题
4)配置表堆内存如何优化


这是第405篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。

UWA社区主页:community.uwa4d.com
UWA QQ群:793972859

Editor

Q:项目升到2022.3.28后观察到在真机上出现了之前没有的内存泄漏状况,用Memory Profiler排查后发现除了一些正常的资源和堆内存有轻微上升外,主要是有一部分Native-UnitySubsystemsObjects-泄露很明显,但没法定位。请问有没有人遇到这个问题?怎么解决?

A:可以参考下这篇官方论坛讨论和复现测试链接:
https://discussions.unity.com/t/memory-leak-in-scriptableobject-containingserializereference-in-android-environment/946666

https://issuetracker.unity3d.com/issues/memory-leak-when-using-serializereference-in-il2cpp-build

根据我们项目中的情况加上自己试验了下,发现触发条件比帖子中还要简单,都不用ScriptableObject+Addressable,只要任意带有[SerializableReference]特性的资源被销毁就会发生泄漏。而且看样子这个问题大概率会出现在所有2022以上及团结引擎的项目中,且目前未被修复。

考虑到使用这些Unity版本一般是基于支持鸿蒙或支持小游戏的主要目的,不大可能回退版本,那么目前处理方法可能就是要尽量避免使用这个特性。

针对以上问题,有经验的朋友欢迎转至社区交流:
https://answer.uwa4d.com/question/670c8262682c7e5cd61bf95c


Rendering

Q:看到一个优化,说不建议用Application.targetFrameRate来设置帧率,如果设置的过低,会把所有(包括输入、输出......)都降低,而采用OnDemandRendering可以只降低输出帧率,不会影响输入,想问下是否可行?
https://docs.unity.cn/cn/2020.3/ScriptReference/Rendering.OnDemandRendering-renderFrameInterval.html

逛论坛发现如下帖子,是在活跃时动态调节renderFrameInterval这种方法,不知是否可以?
https://unity.com/cn/blog/technology/how-on-demand-rendering-can-improve-mobile-performance

public classMenu:MonoBehaviour
{
    // Start is called before the first frame update
    voidStart()
    {
        QualitySettings.vSyncCount =0;
        Application.targetFrameRate =60;
            // When the Menu starts, set the rendering to target 20fps
        OnDemandRendering.renderFrameInterval =3;
    }

    // Update is called once per frame
    voidUpdate()
    {
        if(Input.GetMouseButton(0)||(Input.touchCount >0))
        {
            // If the mouse button or touch detected render at 60 FPS (every frame).
            OnDemandRendering.renderFrameInterval =1;
        }
        else
        {
            // If there is no mouse and no touch input then we can go back to 20 FPS (every 3 frames).
            OnDemandRendering.renderFrameInterval =3;
        }
    }
}

A:是否可行取决于你想要的应用场景和优化效果。OnDemandRendering这个只会影响渲染消耗,对于物理、动画等消耗不会产生影响。

OnDemandRendering.renderFrameInterval = 3

这样设定之后,相当于除了渲染之外的其他逻辑执行三次才会往渲染一次,画面也才会对应的有一次变化。

比如手游上常规的一个操作是玩家如果不操作一段时间就降低帧率并且调暗画面,这种时候预期玩家输入的响应速度并不高,因此使用修改Application.targetFrameRate的方式更好,对于功耗的降低更彻底。

我自己在游戏中使用OnDemandRendering的场景不多,还是要看题主想要应用的场景进行讨论才好判断。以及,最后降低频率带来的优化效果还需要量化测试。

感谢贾伟昊@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/6361dba4a192b2284280fdb7


Editor

Q:遇到一个Unity闪退问题想请大家看看,是否有用Dots遇到过这个问题?

Unity 2022.3.18 + Entities 1.3.2 + IL2CPP,在少部分老ARMv7架构的安卓机子(如Samsung M13, Samsung A13, Samsung J8等)上,EntityManager.AddComponent(entity)会Crash,Crash堆栈在ComponentType.ReadWrite()里,TypeManager.GetTypeIndex()方法是取不到组件的查找ID导致的,组件T是符合非托管标准的结构。

针对以上问题,有经验的朋友欢迎转至社区交流:
https://answer.uwa4d.com/question/6708ce48682c7e5cd61bf8f4


Memory

Q:项目游戏的配置表的堆内存分配还有GC非常多,能不能分享下这块的性能一般是如何优化的?一般优化到什么水平比较合理?

A:有几个常见策略:

  1. 配置表的优化
    序列化库的选择:选择合适的序列化库可以显著减少内存占用。例如,ProtoBuf相比于JSON可以更紧凑地存储数据。

  2. 减少内存分配
    对象池技术:对于经常创建销毁的对象,采用对象池或者Class Pool可以减少频繁的GC。避免频繁创建临时对象:比如在循环中创建数组或集合。建议使用GOT Mono模式采集堆内存分配,查看是哪些函数或者变量导致临时分配较多。

  3. 通常配置表的堆内存驻留占用最好控制在20MB以内。

针对以上问题,有经验的朋友欢迎转至社区交流:
https://answer.uwa4d.com/question/670c83ac3d306f3e9d594d41

封面图来源于网络


今天的分享就到这里。生有涯而知无涯,在漫漫的开发周期中,我们遇到的问题只是冰山一角,UWA社区愿伴你同行,一起探索分享。欢迎更多的开发者加入UWA社区。

UWA官网:www.uwa4d.com
UWA社区:community.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859