Middle+
Kā noteikt atmiņas noplūdi, analizējot dumpu?
sobes.tech AI
Atbilde no AI
Lai noteiktu atmiņas noplūdi dumpā (HPROF failā), tiek izmantoti rīki, kas analizē objektu grafikus kaudzē. Galvenie soļi:
-
Atmiņas dumpa iegūšana:
- Ar Android Studio Memory Profiler.
- Ar komandu
adb shell dumpheap <package_name> /data/local/tmp/dump.hprof. - Ar sistēmas izsaukumu
Debug.dumpHprofData(filePath).
-
Dampa analīze:
- Atveriet dumpu Android Studio: Memory Profiler vai izvēlnē "File" -> "Open".
- Objektu analīze: Objektu kārtošana pēc izmēra (Shallow Size, Retained Size) un piemēru skaita.
- Aizdomīgu objektu meklēšana: Meklējiet klases, kuras būtu jāiznīcina (piem., Activity, Fragment, Contexts), bet tām ir liels piemēru skaits vai nozīmīgs
Retained Size. - Objekta ceļa (Reference Chain) izpēte: Izvēlieties aizdomīgu objektu un izveidojiet tā ceļu uz galvenajiem objektiem (GC saknēm). Tas parādīs, kas tieši tur rokā atsauci, novēršot atkritumu savākšanu.
- Statisko atsauču meklēšana: Statiskie lauki bieži ir avots noplūdēm, ja tie glabā ilgstošas atsauces uz kontekstiem vai View.
- LeakCanary izmantošana: Bibliotēka automatizē noplūžu atklāšanu, dumpu un analīzi reāllaikā, sniedzot detalizētu aprakstu par noplūdes ceļu.
-
Rezultātu interpretācija:
- Garš ceļš uz GC sakni, kas satur atsauces uz objektiem, kuriem būtu jābūt iznīcinātiem, norāda uz problēmu.
- Atsauces no statiskajiem laukiem, AsyncTask, Handleriem ar aizkavējumiem, nepareizi atslēgtiem listeneriem/callbackiem vai singletoniem aktivitātēs vai View bieži ir noplūdes iemesls.
Piemērs analīzes ceļa uz GC sakni Android Studio Memory Profiler:
// Piemērs ceļam uz GC sakni, kas norāda uz noplūdi
// android.app.Activity instances ar mDestroyed=true
// atsauce android.widget.LinearLayout instances
// atsauce android.view.View $ListenerInfo instances
// atsauce com.example.MyActivity$1 instances (anonīma klase, kas realizē View.OnClickListener)
// atsauce com.example.MyActivity instances (noplūde)
Šajā piemērā, anonīma klase (nospiešanas klausītājs) tur neizteiktu atsauci uz MyActivity, lai gan aktivitāte jau būtu jābūt iznīcinātai (mDestroyed=true). Šis klausītājs, iespējams, ir reģistrēts vai turēts citā ilgstošā objektā (piem., statiskā laukā vai singletonā).