内存管理一直是游戏研发的重中之重,当项目运行时的内存压力较大时,更容易达到设备阈值引起闪退。近年来,当出海成为许多游戏公司新选择的同时,我们也发现海外设备对项目的内存情况有着更严格的要求。
为了帮助开发者更全面地了解项目的内存情况,UWA GOT Online最新版本提供了更多关于内存相关的参数,包括:
1. 新增PSS显存数据,配合PSS内存数据,可对项目的闪退风险进行管控;
2. 新增“内存占用”页,包含内存占用汇总、资源内存占用、资源对象快照,更高效地掌握各类资源内存占用趋势及详情;
3. 支持IL2CPP包的堆内存对象快照功能,进一步对堆内存分配情况进行优化。
PSS显存
为了对PSS内存进行进一步的细化拆分,UWA在GOT Online-Overview模式“运行信息”页中新增了PSS显存的内存趋势。
显存即项目运行时用于渲染的资源所占用的内存,该值为底层显卡驱动所反馈的内存分配量,包括纹理资源、Mesh资源以及解析这些资源的相关库所分配的内存等。当显存较高时,容易引起设备闪退,因此需要我们重点关注。
需要注意的是,由于安卓10、安卓11版本的底层限制,该设备在开机后每5分钟才会刷新一次PSS显存。因此在这些设备上,PSS显存曲线会呈现阶梯型变化,这也可能引起报告中PSS内存在某一帧内大幅上涨,所以当我们定位上涨原因时需要追溯前5分钟内发生的事件。
内存占用概览
GOT Online-Overview模式的内存分析模块下新增了内存占用页面,可以帮助开发者快速总览项目中各类资源的内存占用情况。在这个页面中,可以了解项目的内存分布,以及细分定位到哪些资源存在问题,大幅节省了逐个排查的时间。
1. 内存占用表
在内存占用表中,可以展示项目的PSS内存、Reserved Mono、资源内存占用情况,当在Overview模式下同时开启Lua测试时还可以查看到Lua堆内存占用。通过这些内存曲线,开发者可以快速判断是否存在内存泄漏的可能。其中,资源内存占用曲线表示测试过程中UWA采集到的所有资源内存占用之和。
UWA SDK默认会在测试开始、每千帧、场景切换、测试结束和手动进行资源对象快照(如下图“Dump”操作)时触发数据采样,其中仅手动进行资源快照时会采集当前帧所有资源的详细信息。
内存占用表中默认展示PSS内存、Reserved Mono、资源内存占用3条曲线,并且会在横坐标轴上标注资源对象快照帧。
当在Overview模式下同时开启Resource测试时,UWA SDK会采集运行过程中每个资源的详细数据。为了控制数据采集对造成的性能影响,各类资源会在不同帧分别进行数据采集。此时的资源内存占用是一条以60帧为步长的模拟加和曲线,数据准确性相对较低,默认不显示。
由于Overview模式下同时开启Resource测试会产生较大的性能消耗,造成测试时帧率下降、卡顿等,不建议在此时对项目的运行性能进行综合分析。
2. 资源内存占用 和 资源对象快照
资源内存占用表进一步展示了各类资源在测试过程中的内存情况,包括纹理、网格、动画、音频等11项资源。通过表格,不但可以观察各类资源的内存趋势,还可以快速判断项目中各个场景的内存压力主要来自哪类资源。
在未开启Resource模式的报告中选择资源快照帧,或在开启Resource模式的报告中选择任意帧时,网页下方会产生一张资源类型占比预览饼图和具体资源信息。
资源对象快照模块除了能帮助开发者快速判断各类资源在这一帧的内存占比外,还会在右侧的表格中按照内存占用从大到小的顺序,详细列举当前帧各类资源的资源数量、内存占用和推荐值。其中超过推荐值的内存占用项会被红字标出,以便开发者定位需要重点关注的资源类型。
在此表格中点击右侧的操作列,即可快速前往资源内存页下对应的资源的页签,对资源的具体资源使用情况进行进一步分析。
在资源内存页中,也会对资源对象快照帧进行标注,选中快照帧即可查看资源的详细信息。
内存占用页还支持对比功能。打开资源内存占用表右下角的对比模式,在未开启Resource模式时选择任意两个快照帧或在开启Resource模式选择任意帧,即可在页面下方对比两帧间所有类型资源的数量和内存占用大小。
堆内存对象快照
除了资源内存外,UWA也对Mono堆内存数据进行了更详细的采集分析。
在已支持IL2CPP包的Mono堆内存分配数据采集(需要满足Unity 2019.4及以上版本,且勾选Script Debugging选项的)的基础上,最新UWA SDK 2.4.7版本,新增“堆内存泄漏分析”中的“驻留堆内存分配函数”以及“堆内存对象快照”页,以便开发者对运行时的堆内存对象驻留情况进行详细地分析。
在测试时,根据测试开始前设置的Dump规则,在每固定间隔帧或手动Dump时,UWA会对堆内存对象进行数据采集。
开发者可以在“堆内存对象快照”页中的堆内存对象柱状图表中,从“堆内存对象大小”和“堆内存对象个数”两个维度,快速定位到哪些场景中存在需要优化的堆内存驻留问题。
堆内存对象分为Managed Object和内存碎片两部分,其中内存碎片中包含了“空闲激活内存”和“空闲碎片内存”。进行堆内存分配时,会优先使用“空闲激活内存”中可用的内存块,其次才会从“空闲碎片内存”中查找可用的内存块。
在柱状图下方,会显示选中帧所有类型的Managed Object大小、对象类型总数、对象类型个数、内存碎片占比。右侧饼状图会展示前10位和其他类型的对象和的占比,以便开发者对这一帧的堆内存对象情况有一个更直观的了解的同时,快速锁定Mono堆内存瓶颈。
同时,在饼图下方的对象类型表中,也将展示出这一帧所有对象的类型、大小、占比、对象个数等信息。在展开对象类型后,开发者就可以快速定位到调用此对象类型的所有函数和选中函数的倒序调用路径。
通过这张表格,可以更精确地定位堆内存分配的出处,并通过在代码中搜索对应的子函数,更高效地对其堆内存分配进行优化。
希望通过上述功能,UWA可以帮助开发者全面了解项目的内存压力的同时,能更精准地定位这些内存压力具体来自哪些场景和资源,以便快速查找并修复,起到事半功倍的效果。
更多UWA GOT Online的新功能等你来解锁!可前往UWA官网下载SDK,下载链接:UWA | 致力于游戏VR和AR应用提供项目研发解决方案 | 简单优化、优化简单 | 侑虎科技