Ispeziona l’uso della memoria della tua app con Memory Profiler

Il Memory Profiler è un componente di Android Profiler che ti aiuta a identificare le perdite di memoria e il consumo di memoria che può portare a balbuzie, blocchi e persino crash dell’app. Mostra un grafico in tempo reale dell’uso della memoria della tua app e ti permette di catturare un dump dell’heap, forzare le garbage collection e tracciare le allocazioni di memoria.

Per aprire il Memory Profiler, segui questi passi:

  1. Clicca View > Tool Windows > Profiler (puoi anche cliccare Profile nella barra degli strumenti).
  2. Seleziona il dispositivo e il processo dell’app che vuoi tracciare dalla barra degli strumenti di AndroidProfiler. Se hai collegato un dispositivo tramite USB ma non lo vedi elencato, assicurati di aver abilitato il debug USB.
  3. Clicca in qualsiasi punto della timeline MEMORY per aprire il Memory Profiler.

In alternativa, puoi ispezionare la memoria della tua app dalla riga di comando withdumpsys, e anche vedere gli eventi GC in logcat.

Perché dovresti tracciare il profilo della memoria della tua app

Android fornisce un ambiente di memoria gestito: quando determina che la tua app non sta più usando alcuni oggetti, il garbage collector rilascia la memoria inutilizzata nell’heap. Il modo in cui Android va a cercare la memoria inutilizzata viene costantemente migliorato, ma a un certo punto in tutte le versioni di Android, il sistema deve mettere brevemente in pausa il vostro codice. La maggior parte delle volte, le pause sono impercettibili. Tuttavia, se la vostra app alloca la memoria più velocemente di quanto il sistema possa raccoglierla, la vostra app potrebbe essere ritardata mentre il collettore libera abbastanza memoria per soddisfare le vostre allocazioni. Il ritardo potrebbe indurre la vostra applicazione a saltare dei frame e causare una visibile lentezza.

Anche se la vostra applicazione non mostra lentezza, se perde memoria, può conservare quella memoria anche mentre è in background. Questo comportamento può rallentare le prestazioni di memoria del resto del sistema forzando inutili eventi di garbage collectione. Alla fine, il sistema è costretto a uccidere il processo della vostra applicazione per recuperare la memoria. Poi, quando l’utente ritorna alla vostra applicazione, questa deve riavviarsi completamente.

Per aiutare a prevenire questi problemi, dovreste usare il Profiler di memoria per fare quanto segue:

  • Cercare modelli di allocazione della memoria indesiderati nella linea temporale che potrebbero causare problemi di prestazioni.
  • Dump dell’heap Java per vedere quali oggetti stanno utilizzando la memoria in qualsiasi momento. Diversi dump dell’heap per un lungo periodo di tempo possono aiutare a identificare le perdite di memoria.
  • Registra le allocazioni di memoria durante le interazioni normali ed estreme dell’utente per identificare esattamente dove il tuo codice sta allocando troppi oggetti in poco tempo o allocando oggetti che diventano leaked.

Per informazioni sulle pratiche di programmazione che possono ridurre l’uso della memoria della tua app, leggi Gestire la memoria della tua app.

Panoramica del Profiler della memoria

Quando apri per la prima volta il Profiler della memoria, vedrai una linea temporale dettagliata dell’uso della memoria della tua app e strumenti di accesso per forzare la garbage collection, acquisire un heapdump e registrare le allocazioni di memoria.

Figura 1. Il Memory Profiler

Come indicato nella figura 1, la vista predefinita per il Memory Profiler include quanto segue:

  1. Un pulsante per forzare un evento di garbage collection.
  2. Un pulsante per catturare un heap dump.

    Nota: Un pulsante per registrare le allocazioni di memoria appare a destra del pulsante heap dump solo quando è collegato a un dispositivo con Android 7.1 (livello API 25) o inferiore.

  3. Un menu a discesa per specificare la frequenza con cui il profiler cattura le allocazioni di memoria. Selezionare l’opzione appropriata può aiutarti a migliorare le prestazioni dell’app durante la profilazione.
  4. Pulsanti per ingrandire/ridurre la timeline.
  5. Un pulsante per saltare in avanti ai dati della memoria live.
  6. La timeline degli eventi, che mostra gli stati delle attività, gli eventi di input dell’utente e gli eventi di rotazione dello schermo.
  7. La timeline dell’uso della memoria, che include quanto segue:
    • Un grafico impilato di quanta memoria viene usata da ogni categoria di memoria, come indicato dall’asse y a sinistra e dal tasto colore in alto.
    • Una linea tratteggiata indica il numero di oggetti allocati, come indicato dall’asse y sulla destra.
    • Un’icona per ogni evento di garbage collection.

Tuttavia, se stai usando un dispositivo con Android 7.1 o inferiore, non tutti i dati di profilazione sono visibili per default. Se vedi un messaggio che dice, “Advancedprofiling is unavailable for the selected process,” devi abilitare advanced profilingto see the following:

  • Event timeline
  • Number of allocated objects
  • Garbage collection events

On Android 8.0 e superiori, il profiling avanzato è sempre abilitato per le app debuggabili.

Come viene contata la memoria

I numeri che vedete in cima al Memory Profiler (figura 2) si basano su tutte le pagine di memoria privata che la vostra app ha impegnato, secondo il sistema Android. Questo conteggio non include le pagine condivise con il sistema o altre applicazioni.

Figura 2. La legenda del conteggio della memoria in cima al Memory Profiler

Le categorie del conteggio della memoria sono le seguenti:

  • Java: Memoria da oggetti allocati dal codice Java o Kotlin.
  • Native: Memoria da oggetti allocati da codice C o C++.

    Anche se non stai usando C++ nella tua applicazione, potresti vedere un po’ di memoria nativa usata qui perché il framework Android usa la memoria nativa per gestire vari compiti per tuo conto, come quando gestisci le risorse di immagine e altri elementi grafici, anche se il codice che hai scritto è in Java o Kotlin.

  • Grafica: Memoria usata per le code dei buffer grafici per visualizzare i pixel sullo schermo, incluse le superfici GL, le texture GL e così via. (Si noti che questa è memoria condivisa con la CPU, non memoria dedicata alla GPU.)

  • Stack: Memoria utilizzata da entrambi gli stack nativi e Java nella vostra applicazione. Questo di solito si riferisce a quanti threads la vostra app sta eseguendo.

  • Codice: Memoria che la tua applicazione usa per il codice e le risorse, come il bytecode dex, il codice dex ottimizzato o compilato, le librerie .so e i font.

  • Altri: Memoria usata dalla vostra applicazione che il sistema non è sicuro di come classificare.

  • Allocato: Il numero di oggetti Java/Kotlin allocati dalla tua applicazione. Questo non conta gli oggetti allocati in C o C++.

    Quando sei collegato a un dispositivo con Android 7.1 e inferiore, questo conteggio delle allocazioni inizia solo nel momento in cui il Profiler della memoria si è collegato alla tua applicazione in esecuzione. Quindi qualsiasi oggetto allocato prima dell’inizio della profilazione non viene preso in considerazione. Tuttavia, Android 8.0 e superiore include uno strumento di profilazione sul dispositivo che tiene traccia di tutte le allocazioni, quindi questo numero rappresenta sempre il numero totale di oggetti Java in sospeso nella tua app su Android 8.0 e superiore.

Se confrontato con i conteggi della memoria dal precedente strumento Android Monitor, il nuovo Memory Profiler registra la tua memoria in modo diverso, quindi potrebbe sembrare che il tuo uso della memoria sia ora più alto. Il Memory Profiler monitora alcune categorie extra che aumentano il totale, ma se ti interessa solo la memoria dell’heap Java, il numero “Java” dovrebbe essere simile al valore dello strumento precedente. Anche se il numero Java probabilmente non corrisponde esattamente a quello che hai visto in AndroidMonitor, il nuovo numero tiene conto di tutte le pagine di memoria fisica che sono state assegnate all’heap Java della tua app da quando è stata biforcata da Zygote. Quindi questo fornisce una rappresentazione accurata di quanta memoria fisica la tua app sta effettivamente usando.

Visualizza le allocazioni di memoria

Le allocazioni di memoria ti mostrano come ogni oggetto Java e riferimento JNI nella tua memoria è stato allocato. In particolare, il Memory Profiler può mostrare quanto segue sulle allocazioni di oggetti:

  • Quali tipi di oggetti sono stati allocati e quanto spazio usano.
  • La traccia dello stack di ogni allocazione, incluso in quale thread.
  • Quando gli oggetti sono stati deallocati (solo quando si usa un dispositivo con Android 8.0 o superiore).

Se il tuo dispositivo ha Android 8.0 o superiore, puoi visualizzare le tue allocazioni di oggetti in qualsiasi momento come segue: Trascina nella timeline per selezionare la regione per la quale vuoi visualizzare le allocazioni (come mostrato nel video 1). Non c’è bisogno di iniziare una sessione di registrazione, perché Android 8.0 e superiori include uno strumento di profilazione anon-device che tiene costantemente traccia delle allocazioni della tua app.

Video 1. Con Android 8.0 e superiori, seleziona un’area della timeline esistente per visualizzare le allocazioni degli oggetti

Se il tuo dispositivo sta eseguendo Android 7.1 o inferiore, fai clic su Registra allocazioni di memoria nella barra degli strumenti del Profiler della memoria. Durante la registrazione, il Profiler della memoria tiene traccia di tutte le allocazioni che si verificano nella tua applicazione. Quando hai finito, fai clic su Stop recording (lo stesso pulsante; vedi video 2) per visualizzare le allocazioni.

Video 2. Con Android 7.1 e inferiori, devi registrare esplicitamente le allocazioni di memoria

Dopo aver selezionato una regione della linea temporale (o quando finisci una sessione di registrazione con un dispositivo con Android 7.1 o inferiore), l’elenco degli oggetti allocati appare sotto la timeline, raggruppati per nome di classe e ordinati in base al conteggio dell’heap.

Per ispezionare il record di allocazione, seguite questi passi:

  1. Sfogliate l’elenco per trovare oggetti che hanno un conteggio dell’heap insolitamente grande e che potrebbero essere trapelati. Per aiutare a trovare classi conosciute, fate clic sull’intestazione della colonna Nome della classe per ordinare in ordine alfabetico. Quindi fai clic sul nome di una classe. Il riquadroInstance View appare sulla destra, mostrando ogni istanza di quella classe, come mostrato in figura 3.
    • In alternativa, puoi localizzare rapidamente gli oggetti facendo clic su Filter, o premendo Control+F (Command+F su Mac), e inserendo il nome di una classe o pacchetto nel campo di ricerca. Puoi anche cercare per nome di metodo se selezioniArrange by callstack dal menu a discesa. Se volete usare le espressioni regolari, spuntate la casella accanto a Regex. Seleziona la casella accanto aMatch case se la tua query di ricerca è sensibile alle maiuscole e alle minuscole.
  2. Nel pannello Vista istanza, fai clic su un’istanza. La scheda Call Stack appare sotto, mostrando dove quell’istanza è stata allocata e in quale thread.
  3. Nella scheda Call Stack, cliccate con il destro su qualsiasi linea e sceglieteJump to Source per aprire quel codice nell’editor.

Figura 3. I dettagli su ogni oggetto allocato appaiono nell’Instance View sulla destra

Puoi usare i due menu sopra la lista degli oggetti allocati per scegliere quale heap ispezionare e come organizzare i dati.

Dal menu sulla sinistra, scegli quale heap ispezionare:

  • heap di default: Quando nessun heap è specificato dal sistema.
  • heap dell’immagine: L’immagine di avvio del sistema, che contiene le classi che sono precaricate durante l’avvio. Le allocazioni qui sono garantite per non spostarsi mai.
  • heap zygote: L’heap copy-on-write da cui viene biforcato un processo app nel sistema Android.
  • app heap: L’heap primario su cui la tua app alloca la memoria.
  • JNI heap: L’heap che mostra dove vengono allocati e rilasciati i riferimenti Java Native Interface (JNI).

Dal menu sulla destra, scegli come organizzare le allocazioni:

  • Organizza per classe: Raggruppa tutte le assegnazioni in base al nome della classe. Questo è il default.
  • Organizza per pacchetto: Raggruppa tutte le allocazioni in base al nome del pacchetto.
  • Organizza per callstack:

Migliora le prestazioni dell’app durante la profilazione

Per migliorare le prestazioni dell’app durante la profilazione, il profilatore di memoria campiona periodicamente le allocazioni di memoria per default. Quando si eseguono test su dispositivi con APIlevel 26 o superiore, è possibile cambiare questo comportamento utilizzando il menu a tendina Allocation Tracking. Le opzioni disponibili sono le seguenti:

  • Full: Cattura tutte le allocazioni di oggetti in memoria. Questo è il comportamento predefinito in Android Studio 3.2 e precedenti. Se hai un’app che alloca molti oggetti, potresti osservare rallentamenti visibili con la tua app durante la profilazione.
  • Campionato: Campiona le allocazioni di oggetti in memoria a intervalli regolari. Questa è l’opzione predefinita e ha meno impatto sulle prestazioni dell’app durante la profilazione. Le app che allocano molti oggetti in un breve lasso di tempo possono ancora mostrare rallentamenti visibili.
  • Off: Smette di monitorare l’allocazione di memoria della tua app.

Visualizza riferimenti globali JNI

Java Native Interface (JNI) è un framework che permette al codice Java e al codice nativo di chiamarsi a vicenda.

I riferimenti JNI sono gestiti manualmente dal codice nativo, quindi è possibile che gli oggetti Java usati dal codice nativo siano tenuti in vita per troppo tempo. Alcuni oggetti sull’heap Java possono diventare irraggiungibili se un riferimento JNI viene scartato senza essere prima esplicitamente cancellato. Inoltre, è possibile esaurire il limite di riferimento JNI globale.

Per risolvere questi problemi, usate la vista heap JNI nel Memory Profiler per scorrere tutti i riferimenti JNI globali e filtrarli per tipi Java e callstacks nativi. Con queste informazioni, puoi trovare quando e dove vengono creati e cancellati i riferimenti JNI globali.

Mentre la tua applicazione è in esecuzione, seleziona una porzione della linea temporale che vuoi ispezionare e seleziona JNI heap dal menu a discesa sopra l’elenco delle classi.Puoi quindi ispezionare gli oggetti nell’heap come faresti normalmente e fare doppio clic sugli oggetti nella scheda Allocation Call Stack per vedere dove vengono allocati e rilasciati i riferimenti JNI nel tuo codice, come mostrato in figura 4.

Figura 4. Visualizzazione dei riferimenti JNI globali

Per ispezionare le allocazioni di memoria per il codice JNI della tua app, devi distribuire la tua app su un dispositivo con Android 8.0 o superiore.

Per maggiori informazioni su JNI, vedi Consigli JNI.

Native Memory Profiler

L’Android Studio Memory Profiler include un Native Memory Profiler per le app distribuite su dispositivi fisici che eseguono Android 10; il supporto per i dispositivi Android 11 è attualmente disponibile nella release preview di Android Studio 4.2.

Il Native Memory Profiler tiene traccia delle allocazioni/deallocazioni degli oggetti nel codice nativo per un periodo di tempo specifico e fornisce le seguenti informazioni:

  • Allocazioni: Un conteggio degli oggetti allocati tramite malloc() o l’operatore new durante il periodo di tempo selezionato.
  • Deallocazioni: Un conteggio degli oggetti deallocati tramite free() o l’operatoredelete durante il periodo di tempo selezionato.
  • Dimensione delle allocazioni: La dimensione aggregata in byte di tutte le allocazioni durante il periodo di tempo selezionato.
  • Deallocations Size: La dimensione aggregata in byte di tutta la memoria liberata durante il periodo di tempo selezionato.
  • Total Count: Il valore nella colonna Allocations meno il valore nella colonna Deallocations.
  • Dimensione rimanente: Il valore nella colonna Allocations Size meno il valore nella colonna Deallocations Size.

Per iniziare una registrazione, fai clic su Record native allocations nella parte superiore della finestra Memory Profiler:

Quando sei pronto a completare la registrazione, fai clic su Stop recording.

Di default, il Native Memory Profiler usa una dimensione campione di 32 bytes: Ogni volta che 32 byte di memoria vengono allocati, viene presa un’istantanea della memoria. Una dimensione di campionamento più piccola si traduce in istantanee più frequenti, producendo dati più accurati sull’uso della memoria. Una dimensione del campione più grande produce dati meno accurati, ma consumerà meno risorse sul tuo sistema e migliorerà le prestazioni durante la registrazione.

Per cambiare la dimensione del campione del Native Memory Profiler:

  1. Seleziona Run > Edit Configurations.
  2. Seleziona il modulo della tua app nel pannello di sinistra.
  3. Fate clic sulla scheda Profiling e inserite la dimensione del campione nel campo etichettato Intervallo di campionamento della memoria nativa (byte).
  4. Costruite ed eseguite nuovamente la vostra applicazione.

Raccolta di un dump dell’heap

Un dump dell’heap mostra quali oggetti nella vostra applicazione stanno utilizzando la memoria nel momento in cui catturate il dump dell’heap. Specialmente dopo una sessione utente prolungata, un dump dell’heap può aiutare a identificare le perdite di memoria mostrando gli oggetti ancora in memoria che credete non dovrebbero più esserci.

Dopo aver catturato un dump dell’heap, potete vedere quanto segue:

  • Quali tipi di oggetti ha allocato la vostra applicazione e quanti di ognuno.
  • Quanta memoria sta usando ogni oggetto.
  • Dove sono tenuti i riferimenti a ogni oggetto nel tuo codice.
  • Lo stack delle chiamate per dove è stato allocato un oggetto. (Gli stack di chiamata sono attualmente disponibili con un dump dell’heap solo con Android 7.1 e inferiore quando si cattura il dump dell’heap durante la registrazione delle allocazioni.)

Per catturare un dump dell’heap, clicca su Dump Java heap nella barra degli strumenti di Memory Profiler.Durante il dump dell’heap, la quantità di memoria Java potrebbe aumentare temporaneamente.Questo è normale perché il dump dell’heap avviene nello stesso processo della vostra applicazione e richiede un po’ di memoria per raccogliere i dati.

Il dump dell’heap appare sotto la linea temporale della memoria, mostrando tutti i tipi di classe nell’heap, come mostrato in figura 5.

Figura 5. Visualizzazione del dump dell’heap

Se hai bisogno di essere più preciso su quando viene creato il dump, puoi creare un dump dell’heap nel punto critico del codice della tua applicazione chiamandodumpHprofData().

Nella lista delle classi, puoi vedere le seguenti informazioni:

  • Allocazioni: Numero di allocazioni nell’heap.
  • Dimensione nativa: Quantità totale di memoria nativa utilizzata da questo tipo di oggetto (in byte). Questa colonna è visibile solo per Android 7.0 e superiore.

    Vedrai qui la memoria per alcuni oggetti allocati in Java perché Android usa la memoria nativa per alcune classi del framework, comeBitmap.

  • Dimensione nativa: Quantità totale di memoria Java usata da questo tipo di oggetto (in byte).

  • Dimensione trattenuta: Dimensione totale della memoria trattenuta a causa di tutte le istanze di questa classe (in byte).

Si possono usare i due menu sopra l’elenco degli oggetti allocati per scegliere quale heap dump ispezionare e come organizzare i dati.

Dal menu a sinistra, scegliere quale heap ispezionare:

  • heap di default: Quando nessun heap è specificato dal sistema.
  • app heap: L’heap primario su cui l’applicazione alloca la memoria.
  • image heap: L’immagine di avvio del sistema, che contiene le classi che sono precaricate durante l’avvio. Le allocazioni qui sono garantite per non spostarsi mai.
  • zygote heap: L’heap copy-on-write da cui viene biforcato un processo app nel sistema Android.

Dal menu sulla destra, scegli come organizzare le allocazioni:

  • Organizza per classe: Raggruppa tutte le assegnazioni in base al nome della classe. Questo è il default.
  • Organizza per pacchetto: Raggruppa tutte le allocazioni in base al nome del pacchetto.
  • Organizza per callstack: Raggruppa tutte le allocazioni nel loro corrispondente stack di chiamate. Questa opzione funziona solo se si cattura l’heap dump durante la registrazione delle allocazioni. Anche così, è probabile che ci siano oggetti nell’heap che sono stati allocati prima di iniziare la registrazione, quindi queste allocazioni appaiono per prime, semplicemente elencate per nome di classe.

La lista è ordinata per default dalla colonna Retained Size. Per ordinare secondo i valori di una colonna diversa, fai clic sull’intestazione della colonna.

Fai clic sul nome di una classe per aprire la finestra Instance View sulla destra (mostrata in figura 6). Ogni istanza elencata include quanto segue:

  • Profondità: Il numero più breve di salti da qualsiasi radice GC all’istanza selezionata.
  • Dimensione nativa: Dimensione di questa istanza nella memoria nativa.Questa colonna è visibile solo per Android 7.0 e superiori.
  • Shallow Size: Dimensione di questa istanza nella memoria Java.
  • Retained Size: Dimensione della memoria che questa istanza domina (secondo l’albero dei dominatori).

Figura 6. La durata necessaria per catturare un heapdump è indicata nella timeline

Per ispezionare il vostro heap, seguite questi passi:

  1. Sfogliate la lista per trovare gli oggetti che hanno un numero di heap insolitamente grande e che potrebbero essere leakati. Per aiutare a trovare classi conosciute, fai clic sull’intestazione della colonna Class Namecolumn per ordinare in ordine alfabetico. Quindi fai clic sul nome di una classe. Il riquadroInstance View appare sulla destra, mostrando ogni istanza di quella classe, come mostrato in figura 6.
    • In alternativa, puoi individuare rapidamente gli oggetti facendo clic su Filter, o premendo Control+F (Command+F su Mac), e inserendo il nome di una classe o di un pacchetto nel campo di ricerca. Puoi anche cercare per nome di metodo se selezioniArrange by callstack dal menu a discesa. Se volete usare le espressioni regolari, spuntate la casella accanto a Regex. Selezionate la casella accanto aMatch case se la vostra query di ricerca è sensibile alle maiuscole e alle minuscole.
  2. Nel pannello Instance View, cliccate su un’istanza. La tabella dei riferimenti appare sotto, mostrando ogni riferimento a quell’oggetto.

    Oppure, fai clic sulla freccia accanto al nome dell’istanza per visualizzare tutti i suoi campi, e poi fai clic sul nome di un campo per visualizzare tutti i suoi riferimenti. Se volete vedere i dettagli dell’istanza per un campo, cliccate con il tasto destro del mouse sul campo e selezionate Go to Instance.

  3. Nella scheda References, se identificate un riferimento che potrebbe perdere memoria, cliccate con il tasto destro e selezionate Go to Instance. Questo seleziona l’istanza corrispondente dal dump dell’heap, mostrandovi i dati della sua istanza.

Nel vostro dump dell’heap, cercate perdite di memoria causate da uno dei seguenti:

  • Riferimenti a lungo termine a Activity, Context,View, Drawable, e altri oggetti che potrebbero contenere un riferimento al contenitore Activity o Context.
  • Classi interne non statiche, come una Runnable, che possono contenere un’istanza di Activity.
  • Cache che trattengono oggetti più a lungo del necessario.

Salva un heap dump come file HPROF

Dopo aver catturato un heap dump, i dati sono visibili nel Profiler di memoria solo mentre il profiler è in esecuzione. Quando si esce dalla sessione di profilazione, si perde il dump dell’heap. Quindi, se volete salvarlo per rivederlo in seguito, esportate il dump dell’heap in un file HPROF. In Android Studio 3.1 e inferiori, il pulsante Export capture to file si trova sul lato sinistro della barra degli strumenti sotto la timeline; in Android Studio 3.2 e superiori, c’è un pulsante Export Heap Dump alla destra di ogni voce Heap Dump nel pannello Sessions. Nella finestra di dialogo Esporta come che appare, salvate il file con l’estensione .hprof nome file.

Per usare un analizzatore HPROF diverso comejhat, dovete convertire il file HPROF dal formato Android al formato Java SE HPROF.Potete farlo con lo strumento hprof-conv fornito nella directoryandroid_sdk/platform-tools/. Esegui il comando hprof-convcon due argomenti: il file HPROF originale e la posizione in cui scrivere il file HPROF convertito. Per esempio:

hprof-conv heap-original.hprof heap-converted.hprof

Importa un file heap dump

Per importare un file HPROF (.hprof), clicca su Start a new profiling session nel pannelloSessions, seleziona Load from file, e scegli il file dal filebrowser.

Puoi anche importare un file HPROF trascinandolo dal file browser in una finestra di editor.

Rilevamento delle perdite nel Profiler della memoria

Quando si analizza un heap dump nel Profiler della memoria, è possibile filtrare i dati di profilo che Android Studio ritiene possano indicare perdite di memoria per Activity eFragment istanze nella vostra applicazione.

I tipi di dati che il filtro mostra includono i seguenti:

  • Activity istanze che sono state distrutte ma sono ancora referenziate.
  • Fragment istanze che non hanno un FragmentManager valido ma sono ancora referenziate.

In certe situazioni, come le seguenti, il filtro potrebbe produrre falsi positivi:

  • Un Fragment è stato creato ma non è ancora stato usato.
  • Un Fragment è in cache ma non come parte di un FragmentTransaction.

Per usare questa funzione, prima cattura un heap dump o importa un file heap dump in Android Studio. Per visualizzare i frammenti e le attività che forse perdono memoria, selezionate la casella di controllo Activity/Fragment Leaks nel pannello heapdump del Memory Profiler, come mostrato in figura 7.

Figura 7. Filtrare un dump dell’heap alla ricerca di perdite di memoria.

Tecniche per profilare la memoria

Mentre usi il Profiler della memoria, dovresti mettere sotto stress il codice della tua applicazione e provare a forzare le perdite di memoria. Un modo per provocare perdite di memoria nella vostra applicazione è di lasciarla girare per un po’ prima di ispezionare l’heap. Le perdite potrebbero risalire fino alla cima delle allocazioni nell’heap. Tuttavia, più piccola è la perdita, più tempo è necessario far girare l’applicazione per vederla.

Potete anche innescare una perdita di memoria in uno dei seguenti modi:

  • Rotare il dispositivo da verticale a orizzontale e viceversa più volte mentre è in diversi stati di attività. Ruotare il dispositivo può spesso causare la perdita di un oggettoActivity,Context, oView da parte di un’app, perché il sistema crea il Activity e se l’app possiede un riferimento a uno di questi oggetti da qualche altra parte, il sistema non riesce a smaltirlo.
  • Passa tra la tua app e un’altra app mentre sei in diversi stati di attività (passa alla schermataHome, poi torna alla tua app).

Suggerimento: Puoi anche eseguire i passi sopra descritti usando il testframework di themonkeyrunner.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.