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

在 Android 系统中,内存 限制器 (Android 17 及更高版本)的内存限制阈值和 Google Play 管理中心内内存 Vitals 的基准值是“匿名 RSS + 交换空间 ”。此值表示进程实际占用的物理内存压力级别,是必须监控的关键指标,以确保应用稳定运行。

目前,无论是在运行时还是在 Unity 引擎中静态测量,都很难获得与“匿名 RSS + 交换空间”完全一致的内存用量。

为了解决这个问题,本页面介绍了如何在 Unity 引擎环境中使用 Unity Profiler、ProfileRecorder API 和 Unity Memory Profiler 通过近似值以高可靠性跟踪“匿名 RSS + 交换空间”值。

检查运行时内存用量

在 Unity 中,直接测量 Android 在运行时确切的“匿名 RSS + 交换空间”内存 用量而不产生开销可能具有挑战性。不过,您可以使用 Unity 的内置 Profiler 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 中:计算“预留内存总量” - “Gfx 预留内存”。

  • 在发布 build 中:直接使用“预留内存总量”。

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 Memory Profiler

如需执行深入的内存分析并优化游戏,请使用 Unity 内存分析器 软件包。如需找到与 Android OS '匿名 RSS + 交换空间' 用量对应的项,请执行以下操作:

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

    • Untracked
    • Android 运行时
    • 原生
    • 托管式
    在 Unity 内存分析器中设置为“常驻内存”时可查看的内存指标
    图 1.内存说明存储在常驻内存中

总和可作为 Android OS“匿名 RSS + 交换空间”的实用替代项,为游戏内存分析提供切实可行的洞见。

限制

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

  • 这些功能可能会受到限制,具体取决于您的 Unity 版本。

更准确的评估

如需验证确切的 Android OS“匿名 RSS + 交换空间”值,请使用 Perfetto。借助该工具,您可以测量精确的系统级内存用量,并彻底分析游戏的内存占用空间。

Perfetto 界面:显示匿名 RSS、交换及其总和查询。
图 2.Perfetto 界面显示了匿名 RSS、交换空间及其总和查询。