Middle+
Wie erkennt man Speicherlecks bei der Analyse eines Dumps?
sobes.tech KI
Antwort von AI
Um die Speicherleckage in einem Dump (HPROF-Datei) zu erkennen, werden Werkzeuge verwendet, die den Objektgraphen im Heap analysieren. Hauptschritte:
-
Speicher-Dump erstellen:
- Über den Android Studio Memory Profiler.
- Mit dem Befehl
adb shell dumpheap <Paketname> /data/local/tmp/dump.hprof. - Über den Systemaufruf
Debug.dumpHprofData(filePath).
-
Dump analysieren:
- Dump in Android Studio öffnen: im Memory Profiler oder über das Menü "Datei" -> "Öffnen".
- Objekte analysieren: Objekte nach Größe (Shallow Size, Retained Size) und Anzahl sortieren.
- Verdächtige Objekte suchen: Klassen, die zerstört werden sollten (z.B. Activity, Fragment, Contexts), aber viele Instanzen oder eine große
Retained Sizeaufweisen. - Pfad zum Objekt untersuchen (Reference Chain): Wählen Sie ein verdächtiges Objekt aus und verfolgen Sie seinen Weg zu den Wurzel-Objekten (GC roots). Dies zeigt, wer die Referenz hält und die Garbage Collection verhindert.
- Statische Referenzen suchen: Statische Felder sind oft eine Quelle für Lecks, wenn sie langlebige Referenzen auf Kontexte oder Views speichern.
- LeakCanary verwenden: Die Bibliothek automatisiert die Erkennung, den Dump und die Analyse von Lecks in Echtzeit und liefert eine detaillierte Beschreibung des Leckpfads.
-
Ergebnisinterpretation:
- Ein langer Pfad zu GC root, der Referenzen auf Objekte enthält, die zerstört werden sollten, weist auf ein Problem hin.
- Referenzen aus statischen Feldern, AsyncTask, Handlern mit Verzögerungen, nicht ordnungsgemäß abgemeldeten Listeners/Callbacks oder Singletons in Aktivitäten oder Views sind häufig Ursachen für Lecks.
Beispiel für die Analyse des Pfads zu GC root im Android Studio Memory Profiler:
// Beispiel für einen Pfad zu GC root, der auf ein Leck hinweist
// android.app.Activity-Instanz mit mDestroyed=true
// Referenz auf android.widget.LinearLayout
// Referenz auf android.view.View $ListenerInfo
// Referenz auf com.example.MyActivity$1 (anonyme Klasse, die View.OnClickListener implementiert)
// Referenz auf com.example.MyActivity (Leck verursachend)
In diesem Beispiel hält eine anonyme Klasse (Button-Klick-Listener) eine implizite Referenz auf MyActivity, obwohl die Aktivität bereits zerstört sein sollte (mDestroyed=true). Dieser Listener scheint von einem anderen langlebigen Objekt (z.B. statisches Feld oder Singleton) registriert oder gehalten zu werden.