在 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 + 交換」使用情況相應的項目,請按照下列步驟操作:
- 使用 Unity 記憶體分析器擷取快照。
- 開啟快照,然後依序前往「All of Memory」>「Resident Memory on Device」。
計算下列項目的總和:
- 未追蹤
- Android 執行階段
- 原生
- 代管
圖 1. 記憶體說明會儲存在常駐記憶體
總和可實際取代 Android 作業系統 的「匿名 RSS + 交換」,提供可做為行動依據的洞察資料,用於分析遊戲記憶體。
限制:
在記憶體壓力過大的情況下,Android 作業系統可能會壓縮或交換作用中記憶體頁面,以釋出 RAM。由於 Unity 記憶體分析器無法追蹤已交換的記憶體,因此在記憶體用量偏高的情況下,可能會出現差異。
這些功能可能會因 Unity 版本而受到限制。
更準確的評估
如要驗證確切的 Android 作業系統「匿名 RSS + 交換」值,請使用 Perfetto。可讓您精確測量系統層級的記憶體用量,並徹底分析遊戲的記憶體用量。