App che consumano molta memoria

Il daemon LMK (Low Memory Killer) di Android monitora lo stato della memoria di un sistema Android in esecuzione e reagisce alla pressione elevata sulla memoria terminando i processi meno essenziali. Android vitals monitora e segnala le terminazioni LMK percepite dagli utenti in Google Play Console per aiutarti a identificare i problemi di pressione sulla memoria che interessano i tuoi utenti.

Metrica LMK su Android vitals

Android vitals può aiutarti a monitorare e migliorare la percentuale di LMK della tua app. Android Vitals misura un solo tasso di LMK: il tasso di LMK percepiti dall'utente.

La metrica riflette la percentuale di utenti attivi giornalieri che hanno riscontrato almeno un'interruzione per memoria insufficiente (LMK) percepita dall'utente. Un errore LMK percepito dall'utente è un errore LMK che probabilmente è stato notato dall'utente. Ad esempio, sono incluse le interruzioni per memoria insufficiente che si verificano quando la tua app mostra un'attività o è in esecuzione come servizio in primo piano. Queste terminazioni comportano un'uscita immediata e non controllata dal processo. All'utente finale sembra che l'app si sia arrestata in modo anomalo, spesso bypassando i meccanismi standard di salvataggio dello stato del ciclo di vita e causando la perdita dei progressi dell'utente.

Android vitals si concentra su queste terminazioni dei processi perché fungono da proxy ad alta fedeltà per i problemi di gestione errata della memoria. Un tasso di LMK superiore all'1% indica una necessità critica di intervento immediato. Tuttavia, un tasso di LMK più basso non significa necessariamente che la memoria utilizzata dall'app sia ottimale. Questa percentuale più bassa potrebbe indicare che il daemon LMK interrompe di frequente i processi mentre sono in background, il che riduce le prestazioni di "avvio a caldo" e la fluidità del multitasking.

Puoi trovare la metrica nella sezione Stabilità di Android vitals:

Figura 1. Accedi alla percentuale di LMK percepiti dall'utente in Android vitals.

Come per metriche vitals essenziali simili, come ANR e arresti anomali, puoi filtrare le metriche, confrontarle con quelle dei tuoi peer o monitorarne la variazione per un lungo periodo di tempo (fino a 3 anni). I dati sono disponibili per le app esistenti a partire dal 28 gennaio 2025.

Figura 2. Panoramica della percentuale di errori LMK in Android vitals.

Come funziona il daemon Low Memory Killer

La piattaforma Android si basa sul presupposto che la memoria libera sia memoria sprecata. Android cerca di utilizzare sempre tutta la memoria disponibile. Ad esempio, il sistema mantiene le app in memoria dopo che sono state chiuse, in modo che l'utente possa tornare rapidamente a utilizzarle. Per questo motivo, i dispositivi Android spesso funzionano con pochissima memoria libera (consulta la sezione Allocazione della memoria tra i processi).

Per decidere quale processo terminare quando la memoria libera si esaurisce, il daemon Low Memory Killer (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 terminati per primi. Le app in background vengono terminate per prime, i processi di sistema per ultimi. La tabella seguente elenca le categorie di punteggio LMK in ordine decrescente. Gli elementi nella categoria con il punteggio più alto, nella riga uno, vengono terminati 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 3. 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 avviene la garbage collection.
  • Avvia gli eventi di garbage collection e acquisisci uno snapshot dell'heap Java durante l'esecuzione dell'app.
  • Registra le allocazioni della memoria della tua app, ispeziona tutti gli oggetti allocati e visualizza l'analisi dello stack per ogni allocazione.

Se il tuo gioco è in esecuzione 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 stuttering, blocchi e persino arresti anomali dell'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.

Memory Profiler di Android Studio che mostra i riferimenti JNI globali nell'heap.
Figura 4. Visualizzazione dei riferimenti JNI globali in Memory Profiler di Android Studio.

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, che è un profiler integrato che fornisce informazioni di base su dove l'applicazione utilizza la memoria.

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

Il secondo strumento è il pacchetto Memory Profiler, un pacchetto Unity che puoi aggiungere al tuo progetto. Il pacchetto aggiunge un'ulteriore finestra di 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.

Finestra di Unity Memory Profiler che mostra un'analisi dettagliata di uno snapshot della memoria.
Figura 6. Analisi di un'istantanea della memoria utilizzando la finestra Memory Profiler.

Per i workflow di Unity specifici per Android, consulta Controlla la memoria utilizzata con gli strumenti di Unity, Ottimizza la memoria utilizzata in Unity e Esegui il debug degli LMK per i giochi Unity.

Unreal Memory Insights

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

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

A partire da UE 5.4, Memory Insights supporta il tracciamento della memoria con stack di chiamate per i progetti Android.

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

Per i workflow di Unreal specifici per Android, consulta Controlla la memoria utilizzata con Unreal e Ottimizza la memoria utilizzata in Unreal.

Insight sulla memoria ridotta

Android fornisce callback e API che ti consentono di ridurre la memoria utilizzata dal gioco e di determinare il motivo per cui le esecuzioni precedenti del gioco sono state interrotte.

Richiamate

Non registrarti per i callback trim deprecati. Android non fornisce API per rilevare eventi di pressione della memoria nativa prima che il sistema recuperi la memoria e i callback di riduzione della memoria in esecuzione granulari (TRIM_MEMORY_RUNNING_*) non sono stati efficaci nel prevenire le interruzioni per memoria insufficiente. Di conseguenza, Android ha ritirato tutti i livelli di riduzione diversi da TRIM_MEMORY_UI_HIDDEN e TRIM_MEMORY_BACKGROUND. Utilizza questi callback rimanenti o gli equivalenti del ciclo di vita del motore, come OnApplicationPause di Unity e ApplicationWillEnterBackgroundDelegate di Unreal, per rilasciare l'interfaccia utente e le risorse ausiliarie quando il gioco passa in background. Per i dettagli sull'implementazione, consulta Riduci la memoria nei giochi.

Termine 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 termina le app e i giochi che consumano più memoria per liberare memoria per il normale funzionamento del dispositivo.

Le informazioni, gli approfondimenti e le best practice per aiutarti a migliorare l'utilizzo della memoria di gioco includono:

  • Utilizza ApplicationExitInfo: questa API restituisce il motivo per cui l'esecuzione del gioco precedente è stata interrotta dal sistema Android. Utilizza ApplicationExitInfo per verificare se la memoria è insufficiente (REASON_LOW_MEMORY) o se le terminazioni del limitatore di memoria (REASON_MEMORY_LIMITER) sono il motivo di un'uscita dal processo precedente (consulta ApplicationExitInfo per i giochi). Controlla se il gioco è stato terminato a causa della pressione della memoria, in modo da poterlo ottimizzare per utilizzare meno memoria su quel dispositivo.
  • Controlla la RAM fisica totale: per evitare che i giochi vengano interrotti quando sono in primo piano e per adattarli alle funzionalità del dispositivo, controlla la RAM fisica totale per dispositivo per una granularità precisa e regola l'utilizzo della memoria del gioco di conseguenza. Se l'obiettivo è impedire che le app vengano terminate poco dopo essere state spostate in background (per consentire al player di eseguire più attività contemporaneamente), utilizza i callback di riduzione (in particolare TRIM_MEMORY_UI_HIDDEN) per ridurre la memoria utilizzata dal gioco.

Risorse aggiuntive