如何使用 Unity 工具檢查記憶體用量

在 Android 系統中,記憶體限制器 (Android 17 以上版本) 的記憶體限制門檻,以及 Google Play 管理中心記憶體 Vitals 的基準值,都是「匿名 RSS + 交換」。這個值代表程序實際占用的實體記憶體壓力層級,是穩定運作應用程式時必須監控的重要指標。

目前,無論是在執行階段或 Unity 引擎中,都難以測量與「匿名 RSS + 交換」完全相符的記憶體用量。

為解決這個問題,本頁面將介紹如何使用 Unity Profiler、ProfileRecorder API 和 Unity Memory Profiler,在 Unity 引擎環境中追蹤「匿名 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 保留記憶體」指標:

  • 在開發版本中:計算「保留記憶體總量」-「Gfx 保留記憶體」。

  • 在發布版本中:直接使用「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;
    }
}

限制

  • 這些 API 無法追蹤繞過 Unity 記憶體管理工具的記憶體配置 (例如 NativeMalloc(IntPtr size))。

  • 視 Unity 版本而定,這些 API 可能不支援。

分析記憶體細目 (靜態分析)

如果在執行階段偵測到記憶體用量偏高,您需要找出記憶體耗用位置。分析記憶體分配情形,有助於消除不必要的分配作業,並減少遊戲的整體記憶體用量。

Unity 記憶體分析器

如要深入分析記憶體並最佳化遊戲,請使用 Unity 記憶體分析器套件。如要找出與 Android 作業系統「匿名 RSS + 交換」使用情況相應的項目,請按照下列步驟操作:

  1. 使用 Unity 記憶體分析器擷取快照。
  2. 開啟快照,然後依序前往「All of Memory」>「Resident Memory on Device」
  3. 計算下列項目的總和:

    • 未追蹤
    • Android 執行階段
    • 原生
    • 代管
    在 Unity 記憶體分析器中設為「常駐記憶體」時可查看的記憶體指標
    圖 1. 記憶體說明會儲存在常駐記憶體

總和可實際取代 Android 作業系統 的「匿名 RSS + 交換」,提供可做為行動依據的洞察資料,用於分析遊戲記憶體。

限制

  • 在記憶體壓力過大的情況下,Android 作業系統可能會壓縮或交換作用中記憶體頁面,以釋出 RAM。由於 Unity 記憶體分析器無法追蹤已交換的記憶體,因此在記憶體用量偏高的情況下,可能會出現差異。

  • 這些功能可能會因 Unity 版本而受到限制。

更準確的評估

如要驗證確切的 Android 作業系統「匿名 RSS + 交換」值,請使用 Perfetto。可讓您精確測量系統層級的記憶體用量,並徹底分析遊戲的記憶體用量。