在 Android 系统中,内存限制器 (Android 17+) 的内存限制阈值和 Google Play 管理中心内内存 Vitals 的基准值均为“匿名 RSS + 交换”。此值表示进程实际占用的物理内存压力级别,是一个必须监控的关键指标,以确保应用稳定运行。
目前,无论是运行时还是在 Unity 引擎中静态测量,都很难准确衡量与“匿名 RSS + 交换”完全匹配的内存使用量。
为解决此问题,本页介绍了如何在 Unity 引擎环境中,通过使用 Unity Profiler、ProfileRecorder API 和 Unity Memory Profiler 进行近似计算,以高可靠性跟踪“匿名 RSS + 交换”值。
检查运行时的内存用量
在 Unity 中,直接测量 Android 在运行时确切的“匿名 RSS + 交换”内存使用情况而不产生开销可能具有挑战性。不过,您可以使用 Unity 的内置分析器 API 来估算此值(误差在 10% 以内)。
方法 1:使用 Profiler
您可以通过对以下 Profiler API 返回的值求和来估算总内存使用量:
using UnityEngine;
using UnityEngine.Profiling;
public class MemoryMonitor : MonoBehaviour
{
public long GetEstimatedMemoryUsageBytes()
{
long totalReserved = Profiler.GetTotalReservedMemoryLong();
long monoHeapSize = Profiler.GetMonoHeapSizeLong();
return totalReserved + monoHeapSize;
}
}
方法 2:使用 ProfilerRecorder 类
您可以使用 ProfilerRecorder 跟踪预留内存总量和 Gfx 预留内存指标:
在开发 build 中:计算“总预留内存”-“图形预留内存”。
在发布 build 中:直接使用“Total Reserved Memory”。
using Unity.Profiling;
using UnityEngine;
public class MemoryMonitor : MonoBehaviour
{
ProfilerRecorder totalRecorder;
#if DEVELOPMENT_BUILD
ProfilerRecorder gfxRecorder;
#endif
private void OnEnable()
{
totalRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Reserved Memory");
#if DEVELOPMENT_BUILD
gfxRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Gfx Reserved Memory");
#endif
}
private void OnDisable()
{
totalRecorder.Dispose();
#if DEVELOPMENT_BUILD
gfxRecorder.Dispose();
#endif
}
public long GetEstimatedMemoryUsageBytes()
{
#if DEVELOPMENT_BUILD
if (totalRecorder.Valid && gfxRecorder.Valid)
{
return totalRecorder.LastValue - gfxRecorder.LastValue;
}
#else
if (totalRecorder.Valid)
{
return totalRecorder.LastValue;
}
#endif
return 0;
}
}
限制:
绕过 Unity 的内存管理器(例如 NativeMalloc(IntPtr size))的内存分配无法通过这些 API 进行跟踪。
这些 API 可能不受支持,具体取决于您的 Unity 版本。
分析内存细分(静态分析)
如果在运行时检测到内存用量过高,您需要确定内存的消耗位置。通过分析内存分布,您可以消除不必要的分配并减少游戏的总体内存占用。
Unity 内存分析器
如需执行深入的内存分析并优化游戏,请使用 Unity 内存分析器 软件包。如需找到与 Android OS 的“匿名 RSS + 交换空间”用量对应的项,请执行以下操作:
- 使用 Unity 内存分析器捕获快照。
- 打开快照,然后依次前往 All of Memory > Resident Memory on Device。
计算以下各项的总和:
- 未跟踪
- Android 运行时
- 原生
- 托管式
图 1. 记忆描述存储在常驻内存中
总和可作为 Android OS“匿名 RSS + 交换”的实用替代指标,为游戏内存分析提供富有实用价值的分析洞见。
限制:
在内存压力过大的情况下,Android OS 可能会压缩或交换活跃内存页,以释放 RAM。由于 Unity 内存分析器无法跟踪交换内存,因此在高内存用量的情况下可能会出现差异。
这些功能可能会因您的 Unity 版本而受到限制。
更准确的评估
如需验证确切的 Android OS“匿名 RSS + 交换”值,请使用 Perfetto。借助它,您可以精确测量系统级内存用量,并全面分析游戏的内存占用情况。