Middle+
Cum se determină prezența unei scurgeri de memorie la analiza unui dump?
sobes.tech AI
Răspuns de la AI
Pentru detectarea scurgerilor de memorie într-un dump (fișier HPROF), se folosesc instrumente care analizează graficul obiectelor din heap. Pașii principali:
-
Obțineți dump-ul de memorie:
- Prin Memory Profiler din Android Studio.
- Cu comanda
adb shell dumpheap <numele_pachetului> /data/local/tmp/dump.hprof. - Prin apelul de sistem
Debug.dumpHprofData(filePath).
-
Analizați dump-ul:
- Deschideți dump-ul în Android Studio: în Memory Profiler sau prin meniul "File" -> "Open".
- Analizați obiectele: sortați obiectele după dimensiune (Shallow Size, Retained Size) și numărul de instanțe.
- Căutați obiecte suspecte: căutați clase care trebuie distruse (de exemplu, Activity, Fragment, Contexts), dar au multe instanțe sau un
Retained Sizesemnificativ. - Studiați drumul către obiect (Reference Chain): selectați un obiect suspect și urmăriți drumul său către obiectele rădăcină (GC roots). Acest lucru va arăta cine menține referința, prevenind colectarea gunoiului.
- Căutați referințe statice: câmpurile statice sunt adesea o sursă de scurgeri dacă păstrează referințe de lungă durată la contexte sau vizualizări.
- Utilizați LeakCanary: biblioteca automatizează detectarea, dump-ul și analiza scurgerilor în timp real, oferind o descriere detaliată a drumului scurgerii.
-
Interpretarea rezultatelor:
- Un drum lung către GC root, conținând referințe la obiecte care trebuie distruse, indică o problemă.
- Referințele din câmpuri statice, AsyncTask, Handler-e cu întârzieri, listeners/callbacks ne-dezabonate corect sau singleton-uri în activități sau vizualizări sunt adesea cauza scurgerilor.
Exemplu de analiză a drumului către GC root în Android Studio Memory Profiler:
// Exemplu de drum către GC root care indică o scurgere
// android.app.Activity instanță cu mDestroyed=true
// referință la android.widget.LinearLayout
// referință la android.view.View $ListenerInfo
// referință la com.example.MyActivity$1 (clasă anonimă care implementează View.OnClickListener)
// referință la com.example.MyActivity (referință care cauzează scurgerea)
În acest exemplu, o clasă anonimă (ascultător de clic pe buton) menține o referință implicită la MyActivity, deși activitatea ar trebui să fie deja distrusă (mDestroyed=true). Acest ascultător pare să fie înregistrat sau reținut de un alt obiect de lungă durată (de exemplu, un câmp static sau un singleton).