Sobes.tech
Middle+

Kaip nustatyti atminties nutekėjimo buvimą analizuojant dump'ą?

sobes.tech AI

Atsakymas iš AI

Atminties nutekėjimo nustatymui naudojami įrankiai, analizuojantys objektų grafus krūvoje (HPROF failas). Pagrindiniai žingsniai:

  1. Atminties dump'o gavimas:

    • Per Android Studio Memory Profiler.
    • Per komandą adb shell dumpheap <package_name> /data/local/tmp/dump.hprof.
    • Per sisteminį iškvietimą Debug.dumpHprofData(filePath).
  2. Dump'o analizė:

    • Atidarykite dump'ą Android Studio: Memory Profiler arba per meniu "File" -> "Open".
    • Objektų analizė: Rūšiavimas pagal dydį (Shallow Size, Retained Size) ir egzempliorių skaičių.
    • Įtartinų objektų paieška: Suraskite klases, kurios turėtų būti sunaikintos (pvz., Activity, Fragment, Contexts), bet turi daug egzempliorių arba didelį Retained Size.
    • Objekto kelio (Reference Chain) tyrimas: Pasirinkite įtartiną objektą ir sukurkite jo kelią iki pagrindinių objektų (GC šaknų). Tai parodys, kas tiksliai laiko nuorodą, trukdančią surinkti šiukšles.
    • Statinių nuorodų paieška: Statiniai laukai dažnai yra šaltinis nutekėjimams, jei saugo ilgalaikes nuorodas į kontekstus ar View.
    • LeakCanary naudojimas: Biblioteka automatizuoja nutekėjimų aptikimą, dump'ą ir analizę realiu laiku, pateikdama išsamų nutekėjimo kelio aprašymą.
  3. Rezultatų interpretacija:

    • Ilgas kelias iki GC šaknies, turintis nuorodas į objektus, kurie turėtų būti sunaikinti, rodo problemą.
    • Nuorodos iš statinių laukų, AsyncTask, Handler'ių su vėlavimais, netinkamai atjungtų listener'ių ar singleton'ų aktyvumuose ar View dažnai yra nutekėjimo priežastis.

Pavyzdys analizės kelio iki GC šaknies Android Studio Memory Profiler:

// Pavyzdys kelio iki GC šaknies, rodantis nutekėjimą
// android.app.Activity pavyzdys su mDestroyed=true
//   nuoroda android.widget.LinearLayout pavyzdys
//     nuoroda android.view.View $ListenerInfo pavyzdys
//       nuoroda com.example.MyActivity$1 pavyzdys (anoniminis klasės įgyvendinimas, View.OnClickListener)
//         nuoroda com.example.MyActivity pavyzdys (nutekėjimas)

Šiame pavyzdyje, anoniminė klasė (mygtuko paspaudimo klausytojas) laiko nepateiktą nuorodą į MyActivity, nors aktyvumas jau turėtų būti sunaikintas (mDestroyed=true). Šis klausytojas, tikėtina, yra užregistruotas ar laikomas kito ilgalaikio objekto (pvz., statinio lauko ar singletono).