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:
-
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).
-
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ą.
-
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).