Middle+
Ako určiť prítomnosť úniku pamäte pri analýze dumpu?
sobes.tech AI
Odpoveď od AI
Na identifikáciu úniku pamäte v dump-e (HPROF súbore) sa používajú nástroje analyzujúce grafy objektov v haldách. Hlavné kroky:
-
Získanie dumpu pamäte:
- Prostredníctvom Android Studio Memory Profiler.
- Príkazom
adb shell dumpheap <package_name> /data/local/tmp/dump.hprof. - Volaním
Debug.dumpHprofData(filePath).
-
Analýza dumpu:
- Otvorenie dumpu v Android Studio: V Memory Profiler alebo cez menu "File" -> "Open".
- Analýza objektov: Triedenie objektov podľa veľkosti (Shallow Size, Retained Size) a počtu inštancií.
- Hľadanie podozrivých objektov: Hľadajte triedy, ktoré by mali byť zničené (napr. Activity, Fragment, Contexts), ale majú veľký počet inštancií alebo významnú
Retained Size. - Preskúmanie cesty k objektu (Reference Chain): Vyberte podozrivý objekt a vytvorte jeho cestu k koreňovým objektom (GC roots). Ukáže, kto presne drží odkaz, čím zabraňuje zberu odpadu.
- Hľadanie statických odkazov: Statické polia často sú zdrojom únikov, ak uchovávajú dlhodobé odkazy na kontexty alebo View.
- Použitie LeakCanary: Knižnica automatizuje detekciu, dump a analýzu únikov v reálnom čase, poskytujúc podrobný popis cesty úniku.
-
Interpretácia výsledkov:
- Dlhá cesta k GC root, obsahujúca odkazy na objekty, ktoré by mali byť zničené, naznačuje problém.
- Odkazy z statických polí, AsyncTask, Handlerov s oneskoreniami, nesprávne odhlásených listeners/callbacks alebo singletonov na aktivitách alebo v View často spôsobujú úniky.
Príklad analýzy cesty k GC root v Android Studio Memory Profiler:
// Príklad cesty k GC root, ukazujúci na únik
// android.app.Activity inštancia s mDestroyed=true
// references android.widget.LinearLayout inštancia
// references android.view.View $ListenerInfo inštancia
// references com.example.MyActivity$1 inštancia (Anonimná trieda implementujúca View.OnClickListener)
// references com.example.MyActivity inštancia (Leaking this reference)
V tomto príklade, anonymná trieda (počúvací na kliknutie tlačidla) drží nevyjadrenú referenciu na MyActivity, hoci aktivita už má byť zničená (mDestroyed=true). Tento poslucháč je pravdepodobne niekde registrovaný alebo sa drží iným objektom s dlhým životom (napr. statické pole alebo singleton).