Come sapere se un’app Android sta effettivamente perdendo memoria?

Durante lo sviluppo di un’applicazione, ho notato che alla fine si è schiantato perché la JVM non ha potuto allocare più memoria. Usando il comando adb shell dumpsys meminfo, ho potuto vedere che l’heap nativo assegnato cresceva mentre cambiava attività fino a quando non si avvicinava a 16M, quando si arrestava in modo anomalo. Credo di aver corretto il codice per impedire che ciò accada, ma noto che le cifre restituite da ..meminfo variano leggermente e in generale sembrano aumentare leggermente ora.

Fondamentalmente non sono sicuro se dovrebbero tornare agli stessi valori quando avvio e chiudo un’applicazione. Ho queste cifre e non sono sicuro se significano che ho una perdita di memoria o no:

Schermata iniziale, applicazione in memoria (PID visto in DDMS), ma non in esecuzione

adb shell dumpsys meminfo (PID pertinente) fornisce:

native dalvik other total size: 5248 4039 N/A 9287 allocated: 5227 3297 N/A 8524 free: 12 742 N/A 754 (Pss): 2183 3534 1726 7443 (shared dirty): 1976 4640 876 7492 (priv dirty): 2040 1664 940 4644 

L’applicazione è partita dalla schermata principale, le attività avviate sono state:

schermata iniziale -> seleziona la modalità -> Attività 1, quindi tutto retrocesso utilizzando il pulsante Indietro, fino allo schermo di casa

meminfo ora:

  native dalvik other total size: 5572 4231 N/A 9803 allocated: 5497 3153 N/A 8650 free: 74 1078 N/A 1152 (Pss): 2479 3614 1742 7835 (shared dirty): 1976 4632 876 7484 (priv dirty): 2336 1740 956 5032 

processo ripetuto:

  native dalvik other total size: 5696 4231 N/A 9927 allocated: 5211 2949 N/A 8160 free: 392 1282 N/A 1674 (Pss): 2515 3713 1742 7970 (shared dirty): 1976 4632 876 7484 (priv dirty): 2372 1840 956 5168 

Eclipse Memory Analyzer Tool (che non trovo molto informativo) riporta i seguenti “sospetti di perdite”:

 3,143 instances of "java.lang.Class", loaded by "" occupy 736,760 (35.69%) bytes. Biggest instances: class com.ibm.icu4jni.util.Resources$DefaultTimeZones @ 0x40158fe0 - 165,488 (8.02%) bytes. class android.text.Html$HtmlParser @ 0x400eebd8 - 126,592 (6.13%) bytes. class com.google.googlenav.proto.GmmMessageTypes @ 0x43d183d8 - 56,944 (2.76%) bytes. class org.apache.harmony.security.fortress.Services @ 0x40071430 - 51,456 (2.49%) bytes. class android.content.res.Resources @ 0x4004df38 - 33,584 (1.63%) bytes. class android.text.AutoText @ 0x400f23c8 - 31,344 (1.52%) bytes. Keywords java.lang.Class Details » Problem Suspect 2 8,067 instances of "java.lang.String", loaded by "" occupy 497,304 (24.09%) bytes. Keywords java.lang.String Details » Problem Suspect 3 54 instances of "org.bouncycastle.jce.provider.X509CertificateObject", loaded by "" occupy 256,024 (12.40%) bytes. These instances are referenced from one instance of "java.util.HashMap$HashMapEntry[]", loaded by "" Keywords org.bouncycastle.jce.provider.X509CertificateObject java.util.HashMap$HashMapEntry[] 

Tutti i commenti saranno ricevuti con gratitudine

In MAT, non ho quasi mai incontrato un “Leak Suspect” che fosse in realtà una perdita. Quello che stai davvero cercando sono oggetti che vengono mantenuti dopo una scansione GC che non dovrebbe essere.

Ad esempio, supponiamo di avere un’attività di Dashboard in grado di avviare Attività A e B. Avvio di Dashboard, quindi avviare l’attività A, premere il pulsante Indietro, avviare l’attività B e premere il pulsante Indietro.

Utilizzando la vista Debug di Eclipse, puoi forzare un evento di raccolta GC tramite il pulsante “Cause GC”. Ora fai clic sul pulsante “Scarica file HPROF” e avvia MAT. Clicca sul link “Dominator Tree”.

A questo punto, mi aspetto che qualsiasi memoria associata alle attività A e B sia stata raccolta come spazzatura a meno che non ci fosse un errore nel codice. In genere, questo è quello che mi qualificherebbe come una “perdita di memoria” nell’app.

Ciò si verifica molto spesso a causa di contesti conservati, che possono consumare molta memoria poiché i contesti spesso rappresentano componenti di grandi dimensioni (attività, servizi, ecc.).

Tutto ciò che sembra sospetto nella Dominator Tree può essere facilmente studiato tramite l’opzione “Path to GC Roots” -> “exclude weak references” (disponibile tramite il menu del tasto destro del mouse). La vista root di path2gc è probabilmente il modo più semplice per trovare quali oggetti contengono riferimenti a oggetti tali da non poter essere rilasciati.

Una volta individuati i riferimenti imprevisti, è ansible che siano necessari ulteriori scavi nel codice per capire perché. Se ha a che fare con un componente sistema / sistema operativo, grepcode è tuo amico 🙂

La registrazione e l’annullamento della registrazione del ricevitore causeranno perdite di memoria

Ad esempio, se hai registrato il ricevitore con registerReceiver () e nell’applicazione in cui stai provando a registrarlo senza fare la registrazione, questo porterà anche a problemi di perdita di memoria.

ho imparato a conoscere questa cosa dal debugging e dalle correzioni di bug.

In base alla mia esperienza con la creazione di app Android, il sistema operativo sembra lasciare un sacco di spazzatura nella memoria. Tuttavia, quando il dispositivo ne ha bisogno per qualcosa di importante, prenderà (quasi indiscriminatamente) tutto ciò di cui ha bisogno. Anche se sovrascrive un dato in un’altra app attualmente aperta.

A parte questo, ci sono probabilmente molte altre cose in background che influenzano i tuoi numeri, quindi non credo che possiamo trarre da loro qualsiasi informazione conclusiva. Se un’applicazione che hai creato sta perdendo, allora probabilmente c’è qualcosa che potrebbe causare una perdita di memoria in qualsiasi altro ambiente basato su Java. Un articolo del tipo: http://www.ibm.com/developerworks/library/j-leaks/ dovrebbe aiutare a risolvere i problemi più gravi.

Se riscontro problemi di memoria con la mia app, sto utilizzando la versione standalon dello strumento ddbms incluso negli strumenti di sviluppo di Android.

Dai un’occhiata a questo link: http://android-developers.blogspot.com/2009/02/track-memory-allocations.html

Con questo strumento puoi dare un’occhiata al consumo di memoria dal “punto di vista java” in modo da poter vedere quali oggetti stanno bloccando la maggior parte della tua memoria. Questo ti darà la possibilità di localizzare in modo preciso la perdita di memoria che stai riscontrando e di ottimizzare il tuo codice.

L’output che hai dato offre solo una panoramica di Tutta la memoria utilizzata nella tua applicazione ma non come viene utilizzata.

controllando il risultato dello strumento Analizzatore di memoria, lo strumento mat non promette di trovare una memory leak ma mostra problem o suspect base al suo script

Lo strumento MAT rende PIE Chart, Dominator Tree, Path 2 vista GC basata sull’analisi dell’heap dell’applicazione in esecuzione

Lo sviluppatore può analizzare l’utilizzo della memoria in base ai risultati sopra riportati e migliorare la programmazione dell’applicazione

Link molto buono per sapere di più su come rimuovere la perdita di memoria: qui

Inoltre: video di Google IO 2011 che spiega lo strumento MAT , Document , Blog1 e Blog2