The playground

More information here

Speicherlecks in Android – identifizieren, behandeln und vermeiden

Johan Olsson Folgen April 13, 2016 · 9 min read Bei unserem täglichen Streben nach besseren Apps müssen wir als Entwickler viele Dinge berücksichtigen, um auf dem richtigen Weg zu bleiben. Eine häufige Ursache für Abstürze sind Speicherlecks. Dieses spezielle Problem kann sich in verschiedenen Formen manifestieren. In den meisten Fällen steigt die Speichernutzung stetig […]
Johan Olsson
Johan Olsson

Folgen

April 13, 2016 · 9 min read

Bei unserem täglichen Streben nach besseren Apps müssen wir als Entwickler viele Dinge berücksichtigen, um auf dem richtigen Weg zu bleiben. Eine häufige Ursache für Abstürze sind Speicherlecks. Dieses spezielle Problem kann sich in verschiedenen Formen manifestieren. In den meisten Fällen steigt die Speichernutzung stetig an, bis die App keine Ressourcen mehr zuweisen kann und unweigerlich abstürzt. In Java führt dies häufig dazu, dass eine OutOfMemoryException ausgelöst wird. In einigen seltenen Fällen können durchgesickerte Klassen sogar lange genug bleiben, um registrierte Rückrufe zu erhalten, was zu einigen wirklich seltsamen Fehlern führt und allzu oft die berüchtigte IllegalStateException auslöst.

Um anderen zu helfen, den Zeitaufwand für die Codeanalyse zu minimieren, werde ich einige Beispiele für Speicherlecks vorstellen, wie man sie in Android Studio identifiziert und vor allem, wie man sie entfernt.

Haftungsausschluss

Der Zweck dieses Beitrags und seiner Codebeispiele besteht darin, ein tieferes Verständnis der Speicherverwaltung, insbesondere in Java, zu fördern. Die dargestellte allgemeine Architektur, die Verwaltung von Threads und die Handhabung laufender HTTP-Anforderungen sind für eine Produktionsumgebung nicht ideal und dienen lediglich als Beispiel für den angesprochenen Punkt: Speicherlecks in Android sind zu berücksichtigen.

Listener registrieren

Dies sollte eigentlich kein Problem sein, aber allzu oft sehe ich Aufrufe verschiedener Registermethoden, aber ihre nicht registrierten Gegenstücke sind nirgends zu sehen. Dies ist eine potenzielle Quelle von Lecks, da diese Methoden eindeutig so konzipiert sind, dass sie voneinander ausgeglichen werden. Ohne Aufruf der Unregister-Methode behält die Instanz wahrscheinlich eine Referenz bei, lange nachdem das referenzierte Objekt beendet wurde, und beginnt daher, Speicher zu verlieren. In Android ist dies besonders problematisch, wenn es sich bei diesem Objekt um eine Aktivität handelt, da es häufig eine große Datenmenge enthält. Lassen Sie mich Ihnen zeigen, wie das aussehen könnte.

In diesem Beispiel lassen wir uns vom Android locationManager über Standortaktualisierungen informieren. Alles, was wir dazu brauchen, ist der Systemdienst selbst und ein Rückruf, um die Updates zu erhalten. Hier implementieren wir die Standortschnittstelle in der Aktivität selbst, was bedeutet, dass der locationManager einen Verweis auf unsere Aktivität enthält. Wenn das Gerät nun gedreht werden soll, wird eine neue Aktivität erstellt, die die alte Aktivität ersetzt, die bereits für Standortaktualisierungen registriert ist. Da ein Systemdienst definitiv jede Aktivität überlebt, enthält der locationManager weiterhin einen Verweis auf die vorherige Aktivität, sodass der Garbage Collector die Ressourcen, die noch an diese bestimmte Aktivität gebunden sind, nicht zurückfordern kann, was zu einem Speicherverlust führt. Wiederholtes Drehen des Geräts führt dann dazu, dass nicht rückforderbare Aktivitäten den Speicher füllen, was letztendlich zu einer OutOfMemoryException führt.

Aber um einen Speicherverlust zu beheben, müssen wir ihn zuerst finden können. Glücklicherweise verfügt Android Studio über ein integriertes Tool namens Android Monitor, mit dem wir unter anderem die Speichernutzung beobachten können. Alles, was wir wirklich tun müssen, ist den Android-Monitor zu öffnen und auf die Registerkarte Monitore zu gehen, um zu sehen, wie viel Speicher in Echtzeit verwendet und zugewiesen wird.

Der Android-Monitor in Android Studio 2.0

Alle Interaktionen, die die Ressourcenzuweisung verursachen, werden hier wiedergegeben, was es zu einem idealen Ort macht, um die Ressourcennutzung Ihrer Anwendung zu verfolgen. Um unseren Speicherverlust zu finden, müssen wir wissen, was der Speicher zu einem Zeitpunkt enthält, an dem wir den Verdacht haben, dass Speicher verloren gegangen ist. In diesem speziellen Beispiel müssen wir lediglich unsere Anwendung starten, das Gerät einmal drehen und dann die Dump Java Heap-Aktion aufrufen (neben Speicher das dritte Symbol von links). Dadurch wird eine hprof-Datei generiert, die zum Zeitpunkt des Aufrufs der Aktion einen Speicher-Snapshot enthält. Nach einigen Sekunden öffnet Android Studio die Datei automatisch und bietet uns eine übersichtliche visuelle Darstellung des Speichers für eine einfache Analyse.

Ich werde nicht in die Tiefe gehen, wie man durch den riesigen Speicherhaufen navigiert. Stattdessen werde ich Ihre Aufmerksamkeit auf die Analyzer-Aufgaben in der oberen rechten Ecke des Screenshots unten lenken. Alles, was Sie tun müssen, um das im obigen Beispiel eingeführte Speicherleck zu erkennen, ist die Überprüfung Durchgesickerte Aktivitäten erkennen und dann die Wiedergabe zu drücken, damit die durchgesickerte Aktivität unter Analyseergebnisse angezeigt wird.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.