App che consumano molta memoria

La piattaforma Android si basa sul presupposto che la memoria libera è memoria sprecata. Android tenta di utilizzare tutta la memoria disponibile in ogni momento. Ad esempio, il sistema mantiene le app in memoria dopo la chiusura, in modo che l'utente possa tornare rapidamente a utilizzarle. Per questo motivo, i dispositivi Android spesso funzionano con pochissima memoria libera (vedi Allocazione della memoria di Android qui).

Il processo del daemon di interruzione per memoria insufficiente (LMK) di Android monitora lo stato della memoria di un sistema Android in esecuzione e reagisce a una pressione elevata sulla memoria terminando i processi meno essenziali per mantenere le prestazioni del sistema a livelli accettabili.

Per decidere quale processo terminare, il daemon LMK utilizza un punteggio out of memory chiamato oom_adj_score per dare la priorità ai processi in esecuzione. I processi con un punteggio elevato vengono interrotti per primi. Le app in background vengono interrotte per prime; i processi di sistema, per ultimi. La tabella seguente elenca le categorie di punteggio LMK dalla più alta alla più bassa. Gli elementi nella categoria con il punteggio più alto, nella prima riga, vengono eliminati per primi:

Processi Android classificati dal punteggio più alto a quello più basso: app in background, app precedente, app Home,
             servizi, app percepibili, app in primo piano, persistenti, di sistema e native.
Figura 1. Processi Android, con i punteggi più alti in alto e quelli più bassi in basso.

Strumenti di profilazione della memoria

I seguenti strumenti possono aiutarti a trovare e diagnosticare i problemi di memoria nei seguenti modi:

  • Scopri come la tua app alloca la memoria nel tempo. Puoi trovare un grafico in tempo reale della quantità di memoria utilizzata dalla tua app, del numero di oggetti Java allocati e di quando si verifica la garbage collection.
  • Avvia gli eventi di Garbage Collection e acquisisci uno snapshot dell'heap Java durante l'esecuzione dell'app.
  • Registra le allocazioni di memoria della tua app, esamina tutti gli oggetti allocati e visualizza la traccia dello stack per ogni allocazione.

Se il gioco viene eseguito su un motore nativo, utilizza HWAddress Sanitizer per eseguire il debug dell'allocazione della memoria nativa.

Memory Profiler di Android Studio

Android Studio fornisce Memory Profiler come componente di Android Profiler, che ti aiuta a identificare perdite di memoria e saturazione della memoria che possono causare interruzioni, blocchi e persino arresti anomali delle app. Il profiler mostra un grafico in tempo reale dell'utilizzo della memoria della tua app e ti consente di acquisire un dump dell'heap, forzare la garbage collection e monitorare l'allocazione della memoria.

Figura 2. Visualizzazione dei riferimenti JNI globali in Android Studio Memory Profiler.

Strumenti di profilazione della memoria di Unity

Se utilizzi Unity Engine per creare le tue app, puoi seguire le indicazioni per la profilazione della memoria di Unity. Unity offre due strumenti per analizzare la memoria utilizzata nella tua applicazione in Unity.

Il primo è il modulo Memory Profiler, un profiler integrato che fornisce informazioni di base su dove la tua applicazione utilizza la memoria.

Il modulo Memoria mostra le allocazioni di memoria, ad esempio la memoria delle texture e la memoria delle mesh.
Figura 3. Finestra Unity Profiler con il modulo Memoria selezionato.

Il secondo strumento è il pacchetto Memory Profiler, un pacchetto Unity che puoi aggiungere al tuo progetto. Il pacchetto aggiunge un'ulteriore finestra del Memory Profiler all'editor Unity. Memory Profiler ti consente di analizzare la memoria utilizzata nella tua applicazione in modo ancora più dettagliato. Puoi archiviare e confrontare gli snapshot per trovare perdite di memoria o visualizzare il layout della memoria per trovare problemi di frammentazione della memoria.

Figura 4. Analisi di uno snapshot della memoria utilizzando la finestra Memory Profiler.

Unreal Memory Insights

Le app create con Unreal Engine possono utilizzare Unreal Memory Insights per visualizzare informazioni dettagliate sull'allocazione e la deallocazione della memoria, inclusi i tag LLM (Low Level Memory) e gli stack di chiamate associati ai blocchi di memoria.

Il sistema di query Memory Insights può trovare allocazioni attive in qualsiasi momento, identificare le modifiche nella memoria utilizzata, individuare perdite di memoria e distinguere le allocazioni a breve termine da quelle a lungo termine.

A partire da UE 5.4, Memory Insights supporta la traccia della memoria con callstack per i progetti Android.

Tracker Memory Insights che mostra il grafico della memoria principale, il conteggio dell'allocazione in tempo reale e il conteggio degli eventi di allocazione/liberazione.
Figura 5. Tracker Memory Insights di Unreal.

Informazioni sulla memoria in esaurimento

Android fornisce callback e API che ti consentono di ridurre i requisiti di memoria del gioco e determinare il motivo per cui le esecuzioni precedenti del gioco sono state terminate.

Richiamate

Non registrarti per i callback trim ritirati. Android non dispone di API per rilevare eventi di pressione della memoria nativa quando il sistema raggiunge i limiti di memoria. I callback di taglio non sono stati utili per prevenire l'interruzione per esaurimento della memoria, quindi Android ha ritirato tutti tranne TRIM_MEMORY_UI_HIDDEN e TRIM_MEMORY_BACKGROUND.

Interruzione della partita

Android tenta di utilizzare tutta la memoria disponibile per memorizzare nella cache app e giochi per garantire che vengano caricati rapidamente (migliorando l'esperienza utente), ma quando la memoria diventa limitata, il sistema chiude le app e i giochi che consumano più memoria per liberare spazio per il normale funzionamento del dispositivo.

Informazioni, approfondimenti e best practice per aiutarti a ottenere un migliore utilizzo della memoria del gioco includono quanto segue:

  • Utilizza ApplicationExitInfo: questa API restituisce il motivo per cui l'esecuzione precedente del gioco è stata interrotta dal sistema Android. Utilizza ApplicationExitInfoper verificare se la memoria insufficiente è la causa di un'interruzione dell'esecuzione precedente del processo death. Controlla se il gioco è stato chiuso a causa di memoria insufficiente in modo che possa essere ottimizzato per utilizzare meno memoria sul dispositivo.
  • Esamina la RAM fisica totale: Per evitare che i giochi vengano chiusi quando sono in primo piano e per adattarsi alle funzionalità del dispositivo, esamina la RAM fisica totale per dispositivo per una granularità fine per regolare la memoria utilizzata di gioco in base a questo valore. Se l'obiettivo è impedire la chiusura delle app poco dopo il passaggio in background (per consentire al giocatore di svolgere più attività), utilizza i callback trim (TRIM_MEMORY_UI_HIDDEN in particolare) per ridurre la memoria utilizzata del gioco.

Risorse aggiuntive