如何使用 Unity 工具检查内存用量

在 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 + 交换空间”用量对应的项,请执行以下操作:

  1. 使用 Unity 内存分析器捕获快照。
  2. 打开快照,然后依次前往 All of Memory > Resident Memory on Device
  3. 计算以下各项的总和:

    • 未跟踪
    • Android 运行时
    • 原生
    • 托管式
    在 Unity 内存分析器中设置为“常驻内存”时可查看的内存指标
    图 1. 记忆描述存储在常驻内存中

总和可作为 Android OS“匿名 RSS + 交换”的实用替代指标,为游戏内存分析提供富有实用价值的分析洞见。

限制

  • 在内存压力过大的情况下,Android OS 可能会压缩或交换活跃内存页,以释放 RAM。由于 Unity 内存分析器无法跟踪交换内存,因此在高内存用量的情况下可能会出现差异。

  • 这些功能可能会因您的 Unity 版本而受到限制。

更准确的评估

如需验证确切的 Android OS“匿名 RSS + 交换”值,请使用 Perfetto。借助它,您可以精确测量系统级内存用量,并全面分析游戏的内存占用情况。