Nel sistema Android, la soglia del limite di memoria per Memory Limiter (Android 17+) e il valore di riferimento per la metrica di memoria in Google Play Console è 'anonymous RSS + swap'. Questo valore rappresenta il livello di pressione della memoria fisica effettivamente occupata dal processo ed è una metrica fondamentale da monitorare per il funzionamento stabile dell'app.
Al momento, è difficile misurare la memoria utilizzata che corrisponda esattamente a "anonymous RSS + swap" sia in fase di tempo di esecuzione sia staticamente all'interno di Unity Engine.
Per risolvere questo problema, questa pagina spiega come monitorare il valore "anonymous RSS + swap" con elevata affidabilità tramite approssimazione utilizzando Unity Profiler, l'API ProfileRecorder e Unity Memory Profiler in un ambiente Unity Engine.
Controllare la memoria utilizzata in fase di runtime
In Unity, misurare direttamente l'utilizzo esatto della memoria 'anonymous RSS + swap' di Android in fase di runtime senza overhead può essere difficile. Tuttavia, puoi stimare con precisione questo valore (con una varianza di circa il 10%) utilizzando le API Profiler integrate di Unity.
Metodo 1: utilizzare Profiler
Puoi stimare la memoria utilizzata totale sommando i valori restituiti dalle seguenti API Profiler:
using UnityEngine;
using UnityEngine.Profiling;
public class MemoryMonitor : MonoBehaviour
{
public long GetEstimatedMemoryUsageBytes()
{
long totalReserved = Profiler.GetTotalReservedMemoryLong();
long monoHeapSize = Profiler.GetMonoHeapSizeLong();
return totalReserved + monoHeapSize;
}
}
Metodo 2: utilizzare la classe ProfilerRecorder
Puoi monitorare le metriche Total Reserved Memory e Gfx Reserved Memory utilizzando ProfilerRecorder:
Nelle build di sviluppo: calcola 'Total Reserved Memory' - 'Gfx Reserved Memory'.
Nelle build di release: utilizza direttamente "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;
}
}
Limitazione:
Le allocazioni di memoria che ignorano Memory Manager di Unity (ad es. NativeMalloc(IntPtr size)) non possono essere monitorate da queste API.
Queste API potrebbero non essere supportate a seconda della versione di Unity.
Analizzare la suddivisione della memoria (analisi statica)
Se viene rilevato un utilizzo elevato della memoria utilizzata in fase di runtime, devi identificare dove viene consumata la memoria. L'analisi della distribuzione della memoria consente di eliminare le allocazioni non necessarie e ridurre il footprint della memoria complessivo del gioco.
Unity Memory Profiler
Per eseguire un'analisi approfondita della memoria e ottimizzare il gioco, utilizza il pacchetto Unity Memory Profiler. Per individuare gli elementi corrispondenti all'utilizzo di 'anonymous RSS + swap' del sistema operativo Android:
- Acquisisci uno snapshot utilizzando Unity Memory Profiler.
- Apri lo snapshot e vai a All of Memory > Resident Memory on Device.
Calcola la somma dei seguenti elementi:
- Untracked
- Android Runtime
- Native
- Managed
Figura 1. Le descrizioni della memoria sono memorizzate nella memoria residente
La somma totale funge da sostituto pratico per "anonymous RSS + swap" del sistema operativo Android, fornendo informazioni utili per l'analisi della memoria del gioco.
Limitazione:
In caso di forte pressione della memoria, il sistema operativo Android potrebbe comprimere o scambiare le pagine di memoria attive per liberare RAM. Poiché Unity Memory Profiler non può monitorare la memoria scambiata, potrebbero verificarsi discrepanze durante gli scenari di utilizzo elevato della memoria utilizzata.
Queste funzionalità potrebbero essere limitate a seconda della versione di Unity.
Valutazione più accurata
Per verificare i valori esatti di 'anonymous RSS + swap' del sistema operativo Android, utilizza Perfetto. Ti consente di misurare la memoria utilizzata precisa a livello di sistema e di analizzare a fondo il footprint della memoria del gioco.