Memory Profiler è un componente di Android Profiler che aiuta a identificare le perdite di memoria e il tasso di abbandono della memoria che possono causare stuttering, blocchi e persino arresti anomali dell'app. Mostra un grafico in tempo reale dell'utilizzo della memoria da parte dell'app e ti consente di acquisire un dump dell'heap, forzare la garbage collection e monitorare le allocazioni della memoria.
Per aprire Memory Profiler, procedi nel seguente modo:
- Fai clic su Visualizza > Finestre degli strumenti > Profiler (puoi anche fare clic su Profilo
nella barra degli strumenti).
- Seleziona il dispositivo e il processo dell'app che vuoi profilare dalla barra degli strumenti di Android Profiler. Se hai collegato un dispositivo tramite USB, ma non lo vedi nell'elenco, assicurati di aver attivato il debug USB.
- Fai clic in un punto qualsiasi della sequenza temporale MEMORY per aprire Memory Profiler.
In alternativa, puoi esaminare la memoria dell'app dalla riga di comando con dumpsys e anche consultare gli eventi GC in logcat.
Perché dovresti profilare la memoria dell'app
Android fornisce un ambiente di memoria gestito: quando stabilisce che la tua app non utilizza più alcuni oggetti, il garbage collection rilascia la memoria inutilizzata nell'heap. Il modo in cui Android trova la memoria inutilizzata migliora costantemente, ma a un certo punto su tutte le versioni di Android il sistema deve mettere in pausa brevemente il codice. Il più delle volte, le pause sono impercettibili. Tuttavia, se la tua app alloca memoria più velocemente di quanto il sistema possa raccoglierla, l'app potrebbe subire ritardi mentre il raccoglitore libera memoria sufficiente per soddisfare le tue allocazioni. Il ritardo potrebbe far sì che l'app salti i frame e causare una lentezza visibile.
Anche se la tua app non mostra rallentamenti, se perde la memoria, può conservarla anche mentre è in background. Questo comportamento può rallentare le prestazioni della memoria del resto del sistema forzando eventi di garbage collection non necessari. A un certo punto, il sistema deve terminare il processo dell'app per recuperare memoria. Quando l'utente torna alla tua app, questa deve riavviarsi completamente.
Per evitare questi problemi, devi utilizzare Memory Profiler per:
- Cerca nella sequenza temporale eventuali pattern di allocazione della memoria indesiderati che potrebbero causare problemi di prestazioni.
- Esegui il dump dell'heap Java per vedere quali oggetti stanno consumando memoria in un determinato momento. Diversi dump dell'heap per un periodo di tempo prolungato possono aiutare a identificare le perdite di memoria.
- Registra le allocazioni della memoria durante la normale ed estrema interazione dell'utente per identificare esattamente dove il tuo codice sta allocando troppi oggetti in un breve periodo di tempo o allocando oggetti che sono trapelati.
Per informazioni sulle pratiche di programmazione che possono ridurre l'utilizzo della memoria da parte della tua app, leggi Gestire la memoria dell'app.
Panoramica di Memory Profiler
Alla prima apertura di Memory Profiler, viene visualizzata una sequenza temporale dettagliata dell'utilizzo della memoria da parte della tua app e l'accesso agli strumenti per forzare la garbage collection, acquisire un dump dell'heap e registrare le allocazioni della memoria.
Figura 1. Memory Profiler
Come indicato nella Figura 1, la visualizzazione predefinita per Memory Profiler include quanto segue:
- Un pulsante per forzare un evento di garbage collection.
-
Un pulsante per acquisire un dump dell'heap.
Nota: a destra del pulsante di dump dell'heap viene visualizzato un pulsante per registrare le allocazioni della memoria solo se è connesso a un dispositivo con Android 7.1 (livello API 25) o versioni precedenti.
- Un menu a discesa per specificare la frequenza con cui il profiler acquisisce le allocazioni della memoria. La selezione dell'opzione appropriata può aiutarti a migliorare le prestazioni dell'app durante la profilazione.
- Pulsanti per aumentare/diminuire lo zoom della sequenza temporale.
- Pulsante per passare ai dati della memoria in tempo reale.
- La sequenza temporale degli eventi, che mostra gli stati dell'attività, gli eventi di input utente e gli eventi di rotazione dello schermo.
- La sequenza temporale di utilizzo della memoria, che include quanto segue:
- Un grafico in pila che mostra la quantità di memoria utilizzata da ogni categoria di memoria, come indicato dall'asse y a sinistra e dalla chiave colore in alto.
- Una linea tratteggiata indica il numero di oggetti assegnati, come indicato dall'asse y sulla destra.
- Un'icona per ogni evento di garbage collection.
Tuttavia, se utilizzi un dispositivo con Android 7.1 o versioni precedenti, non tutti i dati di profilazione sono visibili per impostazione predefinita. Se visualizzi il messaggio "La profilazione avanzata non è disponibile per il processo selezionato", devi abilitare la profilazione avanzata per visualizzare quanto segue:
- Cronologia degli eventi
- Numero di oggetti allocati
- Eventi di raccolta rifiuti
Su Android 8.0 e versioni successive, la profilazione avanzata è sempre abilitata per le app di cui è possibile eseguire il debug.
Come viene conteggiata la memoria
I numeri che vedi nella parte superiore del Profiler di memoria (figura 2) si basano su tutte le pagine di memoria private per le quali la tua app ha eseguito il commit, secondo il sistema Android. Questo conteggio non include le pagine condivise con il sistema o con altre app.
Figura 2. La legenda del conteggio della memoria nella parte superiore di Memory Profiler
Le categorie nel conteggio della memoria sono le seguenti:
- Java: memoria degli oggetti allocati da codice Java o Kotlin.
Nativo: memoria degli oggetti allocati da codice C o C++.
Anche se non usi C++ nella tua app, potresti vedere che una parte di memoria nativa è utilizzata qui perché il framework Android usa la memoria nativa per gestire varie attività per tuo conto, ad esempio per la gestione di asset immagine e altre immagini, anche se il codice che hai scritto è in Java o Kotlin.
Grafica: memoria utilizzata per le code del buffer della grafica per visualizzare i pixel sullo schermo, incluse le superfici GL, le texture GL e così via. (Tieni presente che si tratta di memoria condivisa con la CPU, non di memoria GPU dedicata).
Stack: memoria utilizzata dagli stack nativi e Java nella tua app. In genere si riferisce al numero di thread in esecuzione nell'app.
Codice: memoria utilizzata dall'app per codice e risorse, ad esempio dex bytecode, codice dex ottimizzato o compilato, librerie .so e caratteri.
Altri: memoria utilizzata dalla tua app che il sistema non sa come classificare.
Allocato: il numero di oggetti Java/Kotlin allocati dalla tua app. Non vengono conteggiati gli oggetti allocati in C o C++.
Se il dispositivo è connesso a un dispositivo con Android 7.1 e versioni precedenti, il conteggio dell'allocazione inizia solo nel momento in cui il Memory Profiler si connette all'app in esecuzione. Di conseguenza, tutti gli oggetti allocati prima di iniziare la profilazione non vengono presi in considerazione. Tuttavia, Android 8.0 e versioni successive includono uno strumento di profilazione sul dispositivo che tiene traccia di tutte le allocazioni, pertanto questo numero rappresenta sempre il numero totale di oggetti Java in sospeso nella tua app su Android 8.0 e versioni successive.
Rispetto al conteggio della memoria dello strumento Monitoraggio Android precedente, il nuovo Memory Profiler registra la memoria in modo diverso, quindi potrebbe sembrare che la tua memoria utilizzata sia ora più elevata. Memory Profiler monitora alcune categorie aggiuntive che aumentano il totale, ma se ti interessa solo la memoria heap Java, il numero "Java" dovrebbe essere simile al valore dello strumento precedente. Anche se il numero Java probabilmente non corrisponde esattamente a ciò che hai visualizzato in Android Monitoring, il nuovo numero include tutte le pagine di memoria fisica che sono state allocate all'heap Java della tua app da quando è stato fork da Zygote. Ciò fornisce una rappresentazione accurata della quantità di memoria fisica utilizzata effettivamente dalla tua app.
Visualizza allocazioni della memoria
Le allocazioni della memoria mostrano come sono stati allocati ogni oggetto Java e riferimento JNI nella tua memoria. In particolare, Memory Profiler può mostrarti le seguenti informazioni sulle allocazioni degli oggetti:
- Quali tipi di oggetti sono stati assegnati e quanto spazio utilizzano.
- L'analisi dello stack di ogni allocazione, incluso in quale thread.
- La localizzazione degli oggetti (solo se si utilizza un dispositivo con Android 8.0 o versioni successive).
Per registrare le allocazioni Java e Kotlin, seleziona Registra allocazioni Java / KOTlin e poi Registra. Se sul dispositivo è installato Android 8 o versioni successive, l'interfaccia utente di Memory Profiler passa a una schermata separata che mostra la registrazione in corso. Puoi interagire con la mini sequenza temporale sopra la registrazione (ad esempio per modificare l'intervallo di selezione). Per completare la registrazione,
seleziona Interrompi .
Su Android 7.1 e versioni precedenti, il profiler della memoria utilizza la registrazione dell'allocazione legacy, che mostra la registrazione nella sequenza temporale finché non fai clic su Interrompi.
Dopo aver selezionato un'area geografica della sequenza temporale (o quando termini una sessione di registrazione con un dispositivo con Android 7.1 o versioni precedenti), viene visualizzato l'elenco degli oggetti allocati, raggruppati per nome di classe e ordinati in base al numero di heap.
Per esaminare il record di allocazione:
- Sfoglia l'elenco per trovare oggetti con conteggi di heap insolitamente grandi e che potrebbero essere divulgati. Per trovare le classi note, fai clic sull'intestazione della colonna Nome classe per ordinare alfabeticamente. quindi fai clic sul nome di un corso. Il riquadro Visualizzazione istanze appare sulla destra, che mostra ogni istanza di quella classe, come mostrato nella figura 3.
- In alternativa, puoi individuare rapidamente gli oggetti facendo clic su Filtra
o premendo Ctrl+F (Comando+F su Mac) e inserendo il nome di una classe o di un pacchetto nel campo di ricerca. Puoi anche cercare in base al nome del metodo se selezioni Ordina per chiamate dal menu a discesa. Se vuoi utilizzare le espressioni regolari, seleziona la casella accanto a Regex. Seleziona la casella accanto a Maiuscole/minuscole se la query di ricerca è sensibile alle maiuscole.
- In alternativa, puoi individuare rapidamente gli oggetti facendo clic su Filtra
- Nel riquadro Visualizzazione istanza, fai clic su un'istanza. La scheda Stack di chiamate viene visualizzata di seguito, che mostra dove è stata allocata l'istanza e in quale thread.
- Nella scheda Stack chiamate, fai clic con il tasto destro del mouse su una riga e scegli Vai all'origine per aprire il codice nell'editor.
Figura 3. I dettagli di ciascun oggetto allocato sono riportati nella Visualizzazione istanza a destra
Puoi utilizzare i due menu sopra l'elenco degli oggetti assegnati per scegliere quale heap esaminare e come organizzare i dati.
Dal menu a sinistra, scegli l'heap da esaminare:
- heap predefinito: quando il sistema non specifica alcun heap.
- heap immagine: l'immagine di avvio del sistema, contenente classi precaricate durante il tempo di avvio. Le allocazioni qui hanno la garanzia che non si spostano o scompariranno.
- heap zigote: l'heap copy-on-write da cui viene eseguito il fork di un processo dell'app nel sistema Android.
- heap dell'app: l'heap principale su cui l'app assegna la memoria.
- heap JNI: l'heap che mostra dove vengono assegnati e rilasciati i riferimenti JNI (Java Native Interface).
Dal menu a destra, scegli come organizzare le allocazioni:
- Ordina per classe: raggruppa tutte le allocazioni in base al nome della classe. Questa è l'impostazione predefinita.
- Ordina per pacchetto: raggruppa tutte le allocazioni in base al nome del pacchetto.
- Ordina per calltack: raggruppa tutte le allocazioni nello stack di chiamate corrispondente.
Migliora le prestazioni dell'app durante la profilazione
Per migliorare le prestazioni dell'app durante la profilazione, per impostazione predefinita il profiler della memoria campiona periodicamente le allocazioni della memoria. Durante i test su dispositivi con API di livello 26 o superiore, puoi modificare questo comportamento utilizzando il menu a discesa Monitoraggio dell'allocazione. Le opzioni disponibili sono le seguenti:
- Completa: acquisisce tutte le allocazioni degli oggetti in memoria. Questo è il comportamento predefinito in Android Studio 3.2 e versioni precedenti. Se hai un'app che assegna molti oggetti, potresti notare rallentamenti visibili nell'app durante la profilazione.
- Campionata: campiona le allocazioni degli oggetti in memoria a intervalli regolari. Questa è l'opzione predefinita e ha un impatto minore sulle prestazioni dell'app durante la profilazione. Le app che allocano molti oggetti in un breve periodo di tempo potrebbero comunque mostrare rallentamenti visibili.
- Off. Interrompe il monitoraggio della quantità di memoria assegnata dall'app.
Visualizza i riferimenti JNI globali
Java Native Interface (JNI) è un framework che consente al codice Java e al codice nativo di chiamarsi tra loro.
I riferimenti JNI sono gestiti manualmente dal codice nativo, pertanto è possibile che gli oggetti Java utilizzati dal codice nativo rimangano attivi troppo a lungo. Alcuni oggetti nell'heap Java potrebbero non essere raggiungibili se un riferimento JNI viene eliminato senza prima essere stato eliminato esplicitamente. Inoltre, è possibile esaurire il limite di riferimento JNI globale.
Per risolvere questi problemi, utilizza la visualizzazione heap JNI in Memory Profiler per sfogliare tutti i riferimenti JNI globali e filtrarli per tipi Java e stack di chiamate nativi. Con queste informazioni puoi scoprire quando e dove vengono creati ed eliminati i riferimenti JNI globali.
Mentre l'app è in esecuzione, seleziona una parte della sequenza temporale che vuoi esaminare e seleziona heap JNI dal menu a discesa sopra l'elenco dei corsi. Puoi quindi esaminare gli oggetti nell'heap come faresti normalmente e fare doppio clic sugli oggetti nella scheda Stack chiamate di allocazione per vedere dove vengono allocati e rilasciati i riferimenti JNI nel codice, come mostrato nella Figura 4.
Figura 4. Visualizzazione dei riferimenti JNI globali
Per ispezionare le allocazioni della memoria per il codice JNI dell'app, devi eseguire il deployment dell'app su un dispositivo con Android 8.0 o versioni successive.
Per ulteriori informazioni su JNI, consulta i suggerimenti per JNI.
Profiler memoria nativo
Android Studio Memory Profiler include un Profiler di memoria nativo per le app distribuite su dispositivi fisici con Android 10. Il supporto per i dispositivi Android 11 è attualmente disponibile nella versione di anteprima di Android Studio 4.2.
Il profilor della memoria nativa tiene traccia di allocazioni/deallocazioni di oggetti nel codice nativo per un periodo di tempo specifico e fornisce le seguenti informazioni:
- Allocazioni: un conteggio di oggetti allocati tramite
malloc()
o l'operatorenew
durante il periodo di tempo selezionato. - Deallocations: un numero di oggetti dealposizionati tramite
free()
o l'operatoredelete
durante il periodo di tempo selezionato. - Dimensioni di allocazione: le dimensioni aggregate in byte di tutte le allocazioni durante il periodo di tempo selezionato.
- Dimensione deallocations: le dimensioni aggregate in byte di tutta la memoria liberata durante il periodo di tempo selezionato.
- Conteggio totale: il valore della colonna Allocazioni meno il valore nella colonna Deallocations.
- Dimensioni rimanenti: il valore della colonna Dimensioni di allocazione meno il valore della colonna Dimensione deallocations.
Per registrare le allocazioni native sui dispositivi con Android 10 e versioni successive, seleziona Registra allocazioni native, quindi Registra. La registrazione continua finché non fai clic su Interrompi
. Dopodiché, l'interfaccia utente di Memory Profiler passa a una schermata separata che mostra la registrazione nativa.
Su Android 9 e versioni precedenti, l'opzione Registra allocazioni native non è disponibile.
Per impostazione predefinita, il Profiler della memoria nativa utilizza una dimensione del campione di 32 byte: ogni volta che vengono allocati 32 byte di memoria, viene acquisito uno snapshot di memoria. Una dimensione inferiore del campione genera snapshot più frequenti, fornendo dati più accurati sull'utilizzo della memoria. Una dimensione maggiore del campione produce dati meno precisi, ma consuma meno risorse del sistema e migliora le prestazioni durante la registrazione.
Per modificare la dimensione del campione di Native Memory Profiler:
- Seleziona Esegui > Modifica configurazioni.
- Seleziona il modulo dell'app nel riquadro a sinistra.
- Fai clic sulla scheda Profilazione e inserisci la dimensione del campione nel campo Intervallo di campionamento della memoria nativo (byte).
- Crea ed esegui di nuovo l'app.
Acquisisci un dump dell'heap
Un dump dell'heap mostra quali oggetti dell'app utilizzano memoria nel momento in cui acquisisci il dump dell'heap. Soprattutto dopo una sessione utente estesa, un dump dell'heap può aiutare a identificare le perdite di memoria mostrando gli oggetti ancora in memoria che ritieni non dovrebbero più essere lì.
Dopo aver acquisito un dump dell'heap, puoi visualizzare quanto segue:
- Quali tipi di oggetti ha allocato la tua app e quanti di ognuno.
- La quantità di memoria utilizzata da ciascun oggetto.
- La posizione dei riferimenti a ciascun oggetto nel codice.
- Lo stack di chiamate a cui è stato allocato un oggetto. (gli stack di chiamate sono attualmente disponibili con un dump dell'heap solo con Android 7.1 e versioni precedenti quando acquisisci il dump dell'heap durante la registrazione delle allocazioni).
Per acquisire un dump dell'heap, fai clic su Acquisisci dump dell'heap, quindi seleziona Registra. Durante il dump dell'heap, la quantità di memoria Java potrebbe aumentare temporaneamente. Questo è normale perché il dump dell'heap si verifica nello stesso processo dell'app e richiede una certa quantità di memoria per raccogliere i dati.
Al termine dell'acquisizione del dump dell'heap da parte del profiler, l'UI di Memory Profiler passa a una schermata separata che mostra il dump dell'heap.
Figura 5. Visualizzazione del dump dell'heap.
Se vuoi essere più preciso in merito alla creazione del dump, puoi creare un dump dell'heap nel punto critico del codice dell'app chiamando dumpHprofData()
.
Nell'elenco dei corsi puoi vedere le seguenti informazioni:
- Allocazioni: numero di allocazioni nell'heap.
Dimensioni native: la quantità totale di memoria nativa utilizzata da questo tipo di oggetto (in byte). Questa colonna è visibile solo per Android 7.0 e versioni successive.
Vedrai la memoria qui per alcuni oggetti allocati in Java, perché Android utilizza la memoria nativa per alcune classi di framework, ad esempio
Bitmap
.Dimensioni superficiali: quantità totale di memoria Java utilizzata da questo tipo di oggetto (in byte).
Dimensioni conservate: dimensione totale della memoria conservata a causa di tutte le istanze di questa classe (in byte).
Puoi utilizzare i due menu sopra l'elenco degli oggetti assegnati per scegliere quali dump dell'heap ispezionare e come organizzare i dati.
Dal menu a sinistra, scegli l'heap da esaminare:
- heap predefinito: quando il sistema non specifica alcun heap.
- heap dell'app: l'heap principale su cui l'app assegna la memoria.
- heap immagine: l'immagine di avvio del sistema, contenente classi precaricate durante il tempo di avvio. Le allocazioni qui hanno la garanzia che non si spostano o scompariranno.
- heap zigote: l'heap copy-on-write da cui viene eseguito il fork di un processo dell'app nel sistema Android.
Dal menu a destra, scegli come organizzare le allocazioni:
- Ordina per classe: raggruppa tutte le allocazioni in base al nome della classe. Questa è l'impostazione predefinita.
- Ordina per pacchetto: raggruppa tutte le allocazioni in base al nome del pacchetto.
- Ordina per calltack: raggruppa tutte le allocazioni nello stack di chiamate corrispondente. Questa opzione funziona solo se acquisisci il dump dell'heap durante la registrazione delle allocazioni. Anche in questo caso, è probabile che ci siano oggetti nell'heap che sono stati allocati prima dell'inizio della registrazione, quindi queste allocazioni appaiono per prime, semplicemente elencate per nome della classe.
L'elenco viene ordinato in base alla colonna Dimensioni conservate per impostazione predefinita. Per ordinare i dati in base ai valori di una colonna diversa, fai clic sull'intestazione della colonna.
Fai clic sul nome di una classe per aprire la finestra Visualizzazione istanza a destra (mostrata nella figura 6). Ogni istanza elencata include:
- Profondità: il numero minimo di hop di qualsiasi radice GC all'istanza selezionata.
- Dimensioni native: la dimensione dell'istanza nella memoria nativa. Questa colonna è visibile solo per Android 7.0 e versioni successive.
- Dimensioni superficiali: la dimensione dell'istanza nella memoria Java.
- Dimensioni mantenute: la dimensione della memoria dominata da questa istanza (come per l'albero dominante).
Figura 6. La durata necessaria per acquisire un dump heap è indicata nella sequenza temporale
Per ispezionare l'heap:
- Sfoglia l'elenco per trovare oggetti con conteggi di heap insolitamente grandi e che potrebbero essere divulgati. Per trovare le classi note, fai clic sull'intestazione della colonna Nome classe per ordinare alfabeticamente. quindi fai clic sul nome di un corso. Il riquadro Visualizzazione istanze appare a destra, che mostra ogni istanza di quella classe, come mostrato nella Figura 6.
- In alternativa, puoi individuare rapidamente gli oggetti facendo clic su Filtra
o premendo Ctrl+F (Comando+F su Mac) e inserendo il nome di una classe o di un pacchetto nel campo di ricerca. Puoi anche cercare in base al nome del metodo se selezioni Ordina per chiamate dal menu a discesa. Se vuoi utilizzare le espressioni regolari, seleziona la casella accanto a Regex. Seleziona la casella accanto a Maiuscole/minuscole se la query di ricerca è sensibile alle maiuscole.
- In alternativa, puoi individuare rapidamente gli oggetti facendo clic su Filtra
- Nel riquadro Visualizzazione istanza, fai clic su un'istanza. La scheda Riferimenti appare di seguito, che mostra tutti i riferimenti all'oggetto.
In alternativa, fai clic sulla freccia accanto al nome dell'istanza per visualizzare tutti i campi, quindi fai clic sul nome di un campo per visualizzare tutti i relativi riferimenti. Se vuoi visualizzare i dettagli dell'istanza per un campo, fai clic con il tasto destro del mouse sul campo e seleziona Vai all'istanza.
- Nella scheda Riferimenti, se identifichi un riferimento che potrebbe perdere memoria, fai clic con il tasto destro del mouse su di esso e seleziona Vai all'istanza. L'istanza corrispondente viene selezionata dal dump dell'heap e verranno mostrati i dati dell'istanza.
Nel dump dell'heap, cerca le perdite di memoria causate da uno dei seguenti motivi:
- Riferimenti di lunga durata a
Activity
,Context
,View
,Drawable
e altri oggetti che potrebbero contenere un riferimento al containerActivity
oContext
. - Classi interne non statiche, come
Runnable
, che possono contenere un'istanzaActivity
. - Cache che contengono oggetti più a lungo del necessario.
Salva un dump dell'heap come file HPROF
Dopo aver acquisito un dump dell'heap, i dati sono visibili in Memory Profiler solo mentre il profiler è in esecuzione. Quando esci dalla sessione di profilazione, perdi il dump dell'heap. Quindi, se vuoi salvarlo per la revisione in un secondo momento, esporta il dump dell'heap in un file HPROF. In Android Studio 3.1 e versioni precedenti, il pulsante Esporta acquisizione in file
si trova sul lato sinistro della barra degli strumenti, sotto la sequenza temporale, mentre in Android Studio 3.2 e versioni successive è presente un pulsante Esporta dump heap a destra di ogni voce Heap Dump nel riquadro Sessioni. Nella finestra di dialogo Esporta come visualizzata, salva il file con l'estensione del nome file
.hprof
.
Per utilizzare un altro analizzatore HPROF come jhat, devi convertire il file HPROF dal formato Android al formato Java SE HPROF.
Puoi farlo con lo strumento hprof-conv
fornito nella directory android_sdk/platform-tools/
. Esegui il comando hprof-conv
con due argomenti: il file HPROF originale e la posizione in cui scrivere il file HPROF convertito. Ecco alcuni esempi:
hprof-conv heap-original.hprof heap-converted.hprof
Importa un file di dump dell'heap
Per importare un file HPROF (.hprof
), fai clic su Avvia una nuova sessione di profilazione
nel riquadro Sessioni, seleziona Carica da file e scegli il file dal browser di file.
Puoi anche importare un file HPROF trascinandolo dal browser di file in una finestra dell'editor.
Rilevamento di perdite in Memory Profiler
Quando analizzi un dump dell'heap in Memory Profiler, puoi filtrare i dati di profilazione che Android Studio ritiene che potrebbero indicare perdite di memoria per le istanze Activity
e Fragment
nella tua app.
I tipi di dati mostrati dal filtro includono:
Activity
istanze che sono state eliminate, ma a cui viene ancora fatto riferimento.- Istanze
Fragment
che non hanno un valoreFragmentManager
valido, ma a cui viene ancora fatto riferimento.
In determinate situazioni, come quelle riportate di seguito, il filtro potrebbe restituire falsi positivi:
- Un elemento
Fragment
è stato creato, ma non è stato ancora utilizzato. - Un
Fragment
viene memorizzato nella cache, ma non fa parte diFragmentTransaction
.
Per utilizzare questa funzionalità, devi prima acquisire un dump dell'heap o importare un file di dump dell'heap in Android Studio. Per visualizzare i frammenti e le attività che potrebbero perdere memoria, seleziona la casella di controllo Attività/perdite di frammenti nel riquadro heapdump del Memory Profiler, come mostrato nella figura 7.
Figura 7. Filtro di un dump dell'heap per rilevare eventuali perdite di memoria.
Tecniche per la profilazione della memoria
Durante l'utilizzo di Memory Profiler, devi sottoporre a stress il codice dell'app e provare a forzare le perdite di memoria. Un modo per provocare perdite di memoria nella tua app è lasciarlo in esecuzione per un po' prima di ispezionare l'heap. Le infiltrazioni possono arrivare alla parte superiore delle allocazioni nell'heap. Tuttavia, più piccola è la fuga, più tempo sarà necessario eseguire l'app per vederla.
Puoi anche attivare una perdita di memoria in uno dei seguenti modi:
- Ruota il dispositivo dall'orientamento verticale a quello orizzontale e poi di nuovo all'indietro più volte in stati di attività diversi. La rotazione del dispositivo spesso può causare la perdita di un oggetto
Activity
,Context
oView
da un'app perché il sistema ricrea l'Activity
e se la tua app contiene un riferimento a uno di questi oggetti altrove, il sistema non può eseguire il garbage collection. - Passa dalla tua app a un'altra app in stati di attività diversi (vai alla schermata Home, quindi torna all'app).
Suggerimento: puoi anche eseguire i passaggi precedenti utilizzando il framework di test monkeyrunner.