Sobes.tech
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:

  1. 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).
  2. 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.
  3. 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ā).