La memoria utilizzata (RSS anonimo + swap) è una metrica di Android vitals che riflette la memoria utilizzata della tua app.
La memoria anonima è la memoria di cui non è stato eseguito il backup in un file di archiviazione, ad esempio le allocazioni dell'heap e la memoria allocata con mmap. Questa metrica acquisisce le allocazioni di memoria dinamica della tua app, inclusi l'heap Java o Kotlin, le allocazioni dell'heap nativo non gestito (dove i dati dei pixel Bitmap risiedono su Android 8.0 (livello API 26) e versioni successive) e gli stack di esecuzione dei thread. Sebbene il sistema operativo possa eliminare la memoria di cui è stato eseguito il backup in un file in caso di pressione, non può eliminare la memoria anonima.
Dimensione del set residente (RSS) è il numero totale di pagine di memoria (sia condivise che non condivise) utilizzate da un processo che vengono mantenute nella RAM fisica. Una pagina è considerata "condivisa" se viene utilizzata da più di un processo (ad esempio app che accedono alla stessa libreria).
Per la memoria anonima, il sistema può scrivere le pagine nello spazio di swap (o zRAM su Android) quando la memoria è sotto pressione. Se necessario, il sistema può leggere di nuovo queste pagine dallo swap.
Nel complesso, la memoria utilizzata (RSS anonimo + swap) è una misura del numero totale di pagine di memoria della tua app di cui non è stato eseguito il backup in un file di archiviazione, inclusa qualsiasi memoria che viene conservata dal sistema nello swap. Il monitoraggio di RSS anonimo + swap ti consente di visualizzare il footprint di memoria effettivo e non eliminabile della tua app.
Se la memoria utilizzata dalla tua app è elevata, approfondisci la questione e risolvi il problema seguendo le indicazioni riportate in questa pagina.
Identificare un utilizzo elevato della memoria
Android vitals
Android vitals condivide la memoria utilizzata della tua app suddivisa in base ai seguenti stati del processo:
- In primo piano: il processo dell'app è visibile. Un valore P99 elevato in questo caso influisce spesso sulle prestazioni percepite dall'utente (jank o arresti anomali OOM) ed è fortemente influenzato da componenti o attività dell'interfaccia utente non eliminati.
- Servizio in primo piano: l'app esegue un servizio in primo piano. Poiché questi servizi sono progettati per attività a lunga esecuzione, sono i candidati ideali per perdite cumulative del ciclo di vita che aumentano in modo aggressivo la coda P99 nel tempo.
- In background: l'app esegue un servizio in background o è stata recentemente messa in background, ma non è ancora memorizzata nella cache. È qui che si accumulano le perdite di elaborazione in background.
- Memorizzata nella cache: l'app è in uno stato di memorizzazione nella cache. Questo stato è molto sensibile alla pressione della memoria di sistema, ad esempio LMK. Poiché il sistema operativo può eliminare questo stato del processo a suo piacimento, questo stato viene fornito solo a scopo di debug.
Per capire come questi stati del processo sono correlati ai callback onTrimMemory,
consulta le indicazioni su come liberare memoria in risposta agli eventi.
Android vitals suddivide anche la memoria utilizzata dalla tua app in bucket RAM. La metrica di memoria utilizzata viene visualizzata come una sequenza temporale di valori percentili giornalieri, insieme al valore giornaliero più recente per il 50° e il 90° percentile.
Una volta identificata la base di riferimento della memoria, segui le indicazioni per diagnosticare e migliorare la memoria utilizzata in eccesso.
Identificare le perdite di memoria utilizzando l'asimmetria della coda
Per identificare le perdite di memoria, cerca una divergenza tra gli utenti tipici (P50) e quelli di coda (P90) in Android vitals. Mentre il bloat degli asset generali aumenta la memoria in modo uniforme in tutti i percentili, le perdite di memoria si accumulano nel tempo, distorcendo notevolmente i dati di coda.
Devi confrontare le metriche P90 e P99 con la base di riferimento P50 in base al nome del processo. Se il rapporto P90/P50 supera 3,5 volte, indica una probabile perdita di memoria durante le sessioni estese. Per alcuni casi d'uso, un rapporto elevato non indica sempre una perdita, ma devi valutare il workflow specifico per determinare se la memoria utilizzata elevata è il comportamento previsto.
Risorse
Diagnosticare l'utilizzo eccessivo della memoria a livello locale
Per iniziare a diagnosticare l'origine della memoria utilizzata in modo eccessivo, puoi acquisire un dump dell'heap con Registra dump dell'heap nelle opzioni sviluppatore, in Android Studio o in Perfetto. Ti consigliamo di iniziare acquisendo un dump dell'heap a livello locale dopo aver testato i percorsi utente principali della tua app.
Ti consigliamo in particolare di testare i seguenti percorsi utente:
- Visualizzazioni web e sessioni del browser in-app
- Scorrimento continuo con molti contenuti multimediali
- Flussi di creazione e modifica degli asset
Per esaminare le potenziali perdite di memoria, identifica innanzitutto i processi che consumano di più utilizzando la tabella Nome del processo nella dashboard di memoria utilizzata di Android vitals. Poi, esegui i percorsi utente corrispondenti a livello locale e raccogli i dump dell'heap in diversi stati del processo (visibile, servizio in primo piano e memorizzato nella cache) per verificare se l'app rilascia memoria dopo essere stata messa in background.
Se esegui il debug dei problemi di memoria utilizzando Android Studio Profiler, puoi anche utilizzare l'integrazione LeakCanary per semplificare il rilevamento delle perdite e il rilevamento delle bitmap duplicate per ottimizzare l'utilizzo delle immagini.
Dopo aver raccolto il dump dell'heap, ti consigliamo di utilizzare le Perfetto AI Skills per analizzare il dump dell'heap e identificare le potenziali origini della memoria utilizzata elevata.
Ecco un esempio di risposta delle competenze AI:
I have completed the analysis of memory leaks and bitmap issues for [app] using the provided Perfetto trace.
Summary of Findings
The investigation identified a critical memory pressure issue caused by massive bitmap retention within the app process.
...
Recommendations for [app]
1. [Library] Image Cache Optimization:
* Review the [Library] caching strategy. Ensure that bitmaps
loaded for animations are released or downsampled when the animation is
not in the foreground.
2. Asset Resolution Audit:
* The 14.7 MB average size suggests full-screen or extremely high-density assets. Audit the [library] files in the native_home component to ensure they are not using unnecessarily large source images.
3. View Lifecycle Management:
* Investigate why 21 [LibraryImage] instances are alive simultaneously. Ensure that views in the bottom
tab are properly detached or their animations are cleared when switching between tabs.
4. Fix Surface Leaks:
* Address the Surface.release failures observed in the logs, as these can lead to both memory leaks and
native resource exhaustion.
Risorse aggiuntive per l'interpretazione dei dump dell'heap
Le seguenti risorse forniscono ulteriori informazioni sull'interpretazione dei dump dell'heap e sul debug della memoria utilizzata:
- Analisi manuale: utilizza le indicazioni di Perfetto Heap Dump Explorer per scoprire come navigare e interpretare le visualizzazioni dei dump dell'heap nell'interfaccia utente di Perfetto.
- Allocazioni Java/Kotlin:leggi Visualizzare il primo dump dell'heap ART per una procedura dettagliata sull'analisi dei dump dell'heap di Android Runtime (ART).
- Allocazioni native: consulta la documentazione di Perfetto Native Profiling per scoprire come raccogliere e analizzare i profili di memoria nativi (C/C++).
- Ispezione CLI:utilizza adb dumpsys meminfo per ottenere una rapida suddivisione della memoria utilizzata dalla tua app su un dispositivo.
- Analisi assistita dall'AI:utilizza le competenze AI di Perfetto per eseguire analisi basate su LLM per rilevare perdite di memoria e allocazioni eccessive nelle tracce.
- Analisi basata su SQL: utilizza le competenze SQL e di analisi delle tracce di Perfetto per eseguire query strutturate e script specializzati per analizzare dati di traccia complessi.
Migliorare l'utilizzo della memoria
Consulta queste sezioni per scoprire di più su come migliorare l'utilizzo della memoria della tua app:
- Ridurre il footprint del codice e delle risorse dell'app
- Monitorare la memoria disponibile e la memoria utilizzata
- Utilizzare costrutti di codice più efficienti in termini di memoria
Per indicazioni dettagliate sulla risoluzione dei problemi di memoria, consulta la guida Gestire la memoria dell'app.