Sobes.tech
Middle+

Hoe bepaal je het bestaan van een geheugenlek bij het analyseren van een dump?

sobes.tech AI

Antwoord van AI

Om geheugenlekken te detecteren in een dump (HPROF-bestand), worden tools gebruikt die de objectgrafiek in de heap analyseren. Belangrijkste stappen:

  1. Verkrijg de geheugen dump:

    • Via de Memory Profiler van Android Studio.
    • Met het commando adb shell dumpheap <pakketnaam> /data/local/tmp/dump.hprof.
    • Met de systeemaanroep Debug.dumpHprofData(filePath).
  2. Analyseer de dump:

    • Open de dump in Android Studio: in Memory Profiler of via het menu "Bestand" -> "Open".
    • Analyseer objecten: Sorteer objecten op grootte (Shallow Size, Retained Size) en aantal.
    • Zoek verdachte objecten: zoek klassen die vernietigd moeten worden (bijvoorbeeld Activity, Fragment, Contexts), maar veel exemplaren of een grote Retained Size hebben.
    • Onderzoek de pad naar het object (Reference Chain): selecteer een verdacht object en traceer de weg naar de root-objecten (GC roots). Dit toont wie de referentie vasthoudt en garbage collection voorkomt.
    • Zoek statische referenties: statische velden zijn vaak een bron van lekken als ze langdurige referenties naar contexten of views opslaan.
    • Gebruik LeakCanary: de bibliotheek automatiseert het detecteren, dumpen en analyseren van lekken in realtime, en geeft een gedetailleerde beschrijving van de lek-weg.
  3. Interpretatie van de resultaten:

    • Een lange pad naar GC root dat verwijzingen bevat naar objecten die vernietigd moeten worden, wijst op een probleem.
    • Verwijzingen vanuit statische velden, AsyncTask, Handlers met vertragingen, niet correct afgemelde listeners/callbacks, of singletonen in activiteiten of views, zijn vaak de oorzaak van lekken.

Voorbeeld van de analyse van de pad naar GC root in Android Studio Memory Profiler:

// Voorbeeld van een pad naar GC root dat wijst op een lek
// android.app.Activity instantie met mDestroyed=true
//   verwijzing naar android.widget.LinearLayout
//     verwijzing naar android.view.View $ListenerInfo
//       verwijzing naar com.example.MyActivity$1 (anonieme klasse die View.OnClickListener implementeert)
//         verwijzing naar com.example.MyActivity (lekveroorzakend)

In dit voorbeeld houdt een anonieme klasse (knop klik listener) een impliciete verwijzing naar MyActivity, terwijl de activiteit al vernietigd zou moeten zijn (mDestroyed=true). Deze listener lijkt geregistreerd of vastgehouden te worden door een ander langdurig object (bijvoorbeeld een statisch veld of singleton).