Heap Dump: Was es ist, Heap-Analyse und Beseitigung von Speicherlecks

Autor: IT Sectr Veröffentlicht: 2026-05-07 Lesezeit: 10 Min.

Heap Dump (Haldendump) ist eine Momentaufnahme des dynamischen Speichers einer Anwendung, die vollständige Informationen über alle lebenden Objekte enthält: ihre Klassen, Größen, gegenseitigen Referenzen und Erreichbarkeit von GC-Wurzeln. Heap Dump ist das primäre Werkzeug zur Analyse von Speicherlecks und Optimierung des Ressourcenverbrauchs. Laut Android Developers kann die Heap-Dump-Analyse bis zu 95% der Speicherlecks erkennen, einschließlich zyklischer Referenzen, vergessener Listener und nicht freigegebener statischer Referenzen.

Wichtige Erkenntnisse

  • Heap Dump ist eine Momentaufnahme des gesamten dynamischen Speichers einer Anwendung mit Informationen über jedes Objekt und die Referenzen zwischen ihnen.
  • Android Studio Memory Profiler ermöglicht das Erfassen von Heap-Dumps in Echtzeit für Java- und Kotlin-Anwendungen.
  • Xcode Instruments bietet das Allocations-Werkzeug zum Erstellen und Analysieren von Heap-Dumps auf iOS/macOS.
  • Shallow und Retained Size sind die wichtigsten Kennzahlen: Shallow ist die Größe des Objekts selbst, Retained ist die Größe des Objekts plus aller Objekte, die es hält.
  • Die Analyse eines Heap-Dumps umfasst die Suche im Dominator Tree, die größten Retained Objects und die kürzesten Pfade zu GC-Wurzeln.

Was ist ein Heap-Dump und warum wird er benötigt

Heap-Dump ist ein vollständiger Dump des Heaps der virtuellen Maschine — der Speicherbereich, in dem sich alle dynamisch erstellten Objekte befinden. In Java und Kotlin ist es der Dalvik/ART-Heap auf Android, in Swift und Objective-C der ARC-verwaltete Heap auf iOS. Ein Heap-Dump erfasst jedes Objekt, seine Klasse, Größe, Felder, Referenzen auf andere Objekte und Erreichbarkeitsflags von GC-Wurzeln (Stapelvariablen, statische Felder, JNI-Referenzen).

Der Hauptzweck eines Heap-Dumps ist die Erkennung von Speicherlecks. Ein Leck tritt auf, wenn eine Anwendung weiterhin Referenzen auf Objekte hält, die nicht mehr benötigt werden, und so deren Sammlung durch den Garbage Collector verhindert. Typische Ursachen: Ereignis-Listener, die beim Zerstören einer Activity nicht abgemeldet wurden; Singletons mit Referenzen auf Kontext; Closures, die self erfassen; statische Sammlungen, in die Daten ohne Entfernung hinzugefügt werden. Ein Heap-Dump liefert ein genaues Bild: welche Objekte „leben“, welche unnötig sind und wer genau sie referenziert.

Laut Google I/O stehen mehr als 60% der Crash-Berichte von Android-Apps im Zusammenhang mit OutOfMemoryError, und in 80% der Fälle ist die Ursache ein Speicherleck, das durch einen Heap-Dump erkennbar ist. Bei iOS-Apps ist die Situation ähnlich: Lecks aufgrund von Retain Cycles sind eine der häufigsten Crash-Ursachen, die durch das Allocations-Instrument in Xcode identifiziert werden.

Wann ein Heap-Dump benötigt wird

Ein Heap-Dump sollte bei folgenden Symptomen durchgeführt werden: Die App verbraucht bei wiederholten Aktionen (Hin- und Hernavigieren zwischen Bildschirmen) linear Speicher; nach dem Schließen eines Bildschirms kehrt der Speicher nicht auf das Ausgangsniveau zurück; es treten OutOfMemoryError oder Speicherwarnungen unter iOS auf; die App wird aufgrund von Speicherüberschreitung beendet. Die regelmäßige Erfassung von Heap-Dumps ist Teil des Engineering-Kulturprotokolls in großen Mobilprojekten wie Instagram und Spotify.

Heap-Dump in Android Studio: Erfassung und Analyse

Android Studio bietet den Memory Profiler — ein integriertes Werkzeug zur Erfassung von Heap-Dumps in Echtzeit. Zugänglich über View → Tool Windows → Profiler. Nach dem Starten der App wählen Sie die Sitzung aus, gehen Sie zum Tab Memory und klicken Sie auf Dump Java Heap. Android Studio pausiert die App, führt einen ART-Heap-Dump durch und lädt das Ergebnis zur Analyse. Die Dump-Datei hat das Format .hprof — der HPROF-Standard, der mit den meisten Speicheranalysetools kompatibel ist.

Nach dem Laden des Dumps zeigt Android Studio eine Objekttabelle mit Spalten an: Allocations (Anzahl der Instanzen), Native Size (Speicher außerhalb des ART-Heaps), Shallow Size (Speicher des Objekts selbst), Retained Size (Speicher des Objekts einschließlich seines gesamten Subgraphen). Das Filtern nach Klassennamen, Sortieren nach Retained Size und Suchen nach Paketen ermöglicht es, problematische Bereiche schnell zu finden.

kotlin
// Typisches Leck — ein Listener, der in onDestroy nicht abgemeldet wurde
class MainActivity : AppCompatActivity() {
    private val sensorManager by lazy {
        getSystemService(SENSOR_SERVICE) as SensorManager
    }
    private val listener = MySensorListener()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        sensorManager.registerListener(listener,
            sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
            SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onDestroy() {
        super.onDestroy()
        // ❌ sensorManager.unregisterListener(listener) fehlt
        // → Activity wird nicht vom GC erfasst, Heap-Dump zeigt das Leck
    }
}

Dominator-Tree-Analyse in Android Studio

Der Tab Dominator Tree zeigt Objekte an, die die meiste Speicher halten. Wenn ein Objekt aus dem Dominator Tree entfernt wird, wird der gesamte von ihm gehaltene Speicher für die Garbage Collection verfügbar. Dies ist ein Schlüsselwerkzeug: Statt Tausende von Objekten zu durchsuchen, konzentrieren Sie sich auf 10–20, die 80–90% des Speichers kontrollieren. Laut Google ist die Dominator-Tree-Analyse der effektivste Weg, einen Leckpunkt zu finden, und reduziert die Analysezeit von Stunden auf Minuten.

Heap-Dump in Xcode Instruments: Allocations und Leaks

Xcode Instruments bietet zwei Werkzeuge für die Arbeit mit Heap-Dumps: Allocations — Erfassung von Heap-Dumps mit Echtzeit-Verbrauchsdiagramm; Leaks — automatische Suche nach Lecks durch Retain-Cycle-Analyse. Allocations zeigt alle Objekte im Heap, ihre Größe, Anzahl der Erstellungen (Allocations) und Freigaben (Deallocations). Die Differenz zwischen Erstellungs- und Freigabeanzahl für eine bestimmte Klasse weist auf ein potenzielles Leck hin.

Die Erfassung eines Heap-Dumps in Allocations erfolgt über die Schaltfläche Snapshot Memory — das Werkzeug pausiert die App und erstellt einen vollständigen Dump. Danach stehen die Standardansichten zur Verfügung: Objektliste nach Klasse, Call Tree für jedes Objekt und ein Berichtsgenerator. Im Gegensatz zu Android Studio verwendet Xcode nicht .hprof, sondern speichert Daten in seinem eigenen .trace-Format, das mit Instruments kompatibel ist.

swift
// Typisches iOS-Leck — Retain Cycle durch einen Closure
class NetworkManager {
    var onComplete: ((Data) -> Void)?

    func startRequest() {
        // ❌ Closure erfasst self — Retain Cycle
        onComplete = { data in
            self.process(data)
        }
    }
    func process(_ data: Data) {}
}

Das Leaks-Instrument erkennt automatisch Retain Cycles und Lecks durch Referenzgraph-Analyse. Es markiert leckende Objekte mit einem violetten Symbol und zeigt den Pfad zur Wurzel (GC Root). Zur Beseitigung eines Retain Cycles reicht es aus, [weak self] oder [unowned self] im Closure-Capture hinzuzufügen. Die regelmäßige Ausführung des Leaks-Instruments ist ein obligatorischer CI-Pipeline-Schritt in Teams, die Swift für die iOS-Entwicklung verwenden.

swift
// Behebung — schwache Referenz auf self
onComplete = { [weak self] data in
    guard let self else { return }
    self.process(data)
}

Shallow Size, Retained Size und Dominator Tree

Für eine korrekte Heap-Dump-Analyse müssen drei Schlüsselkennzahlen verstanden werden. Shallow Size ist die Speichermenge, die direkt vom Objekt belegt wird: seine Felder, Header und Ausrichtung. Für ein typisches Java/Kotlin-Objekt beträgt die Shallow Size 16–40 Bytes. Retained Size ist die Shallow Size des Objekts plus die gesamte Shallow Size aller Objekte, die nur über dieses Objekt erreichbar sind (d.h. bei seiner Entfernung zu Müll würden). Die Retained Size zeigt die tatsächliche Auswirkung des Objekts auf den Speicherverbrauch.

KennzahlBeschreibungBeispiel
Shallow SizeGröße des Objekts selbst in BytesBitmap (100×100) = 40.016 B
Retained SizeShallow Size + alles, was es hältActivity mit View Tree = 2–5 MB
Deep SizeRetained Size + verschachtelte Objekte aus anderen GraphenScrollView mit Adapter = 10–50 MB

Dominator Tree ist eine Struktur, in der jedes Objekt seinen „Dominator“ referenziert — das Objekt, das seine Erreichbarkeit kontrolliert. Wenn der Dominator entfernt wird, werden alle Objekte seines Unterbaums zu Müll. Die Dominator-Tree-Analyse ist der schnellste Weg, um herauszufinden, welches Objekt den meisten Speicher hält. Laut Eclipse MAT werden 90% der Lecks durch Überprüfung der Top-20 des Dominator Tree in 5 Minuten erkannt.

Speicherleckanalyse mittels Heap-Dump

Der Prozess der Leckanalyse mittels Heap-Dump besteht aus mehreren Schritten. Schritt 1: Führen Sie die Aktion aus, die Speicher freigeben soll (schließen Sie den Bildschirm, beenden Sie den Vorgang). Schritt 2: Rufen Sie GC auf und erstellen Sie einen Heap-Dump. Schritt 3: Finden Sie Objekte, die hätten zerstört werden sollen. Schritt 4: Führen Sie für das verdächtige Objekt Path to GC Roots aus — die Referenzkette, die das Objekt am Leben hält. Die letzte Referenz in der Kette ist die Leckursache.

Path to GC Roots

Die Funktion Path to GC Roots ist in Android Studio Profiler, Eclipse MAT und Xcode Instruments verfügbar. Sie zeigt die kürzeste Referenzkette von einer GC-Wurzel zum problematischen Objekt. Durch Ausschluss von schwachen (Weak) und weichen (Soft) Referenzen erhalten Sie nur die starken (Strong) — jene, die tatsächlich die Sammlung verhindern. Laut Square Engineering werden 70% der Lecks in Android-Apps durch nur zwei Muster verursacht: statische Referenzen auf Activity oder Context und registrierte, aber nicht abgemeldete Listener.

kotlin
// Beispiel eines Lecks durch eine statische Referenz
object AppCache {
    private val cache = mutableMapOf<String, Any>()

    fun storeActivityReference(activity: Activity) {
        cache["current_activity"] = activity // ❌ Leck!
    }
}

// Behebung: schwache Referenz
object AppCacheFixed {
    private val cache = mutableMapOf<String, WeakReference<Any>>()
}

Vergleich zweier Heap-Dumps

Die Technik des Vergleichsmodus ist eine der effektivsten Methoden zur Leckerkennung. Erstellen Sie einen Heap-Dump vor und nach einer wiederholten Aktion. Vergleichen Sie die Instanzanzahlen der Schlüsselklassen: Wenn die Anzahl der Activity gestiegen ist, obwohl alle Aktivitäten geschlossen wurden — ist es ein Leck. Android Studio und Eclipse MAT unterstützen den automatischen Dump-Vergleich mit Hervorhebung von Unterschieden. Laut Google ermöglicht der Dump-Vergleich das Auffinden von Lecks, die bei einer Einzelanalyse unsichtbar sind, durch Akkumulationseffekt.

Praktische Empfehlungen zur Reduzierung des Speicherverbrauchs

Basierend auf der Heap-Dump-Analyse in realen Projekten wurden bewährte Speicheroptimierungspraktiken entwickelt. Verwenden Sie WeakReference für Caches, Callbacks und Kontextreferenzen in langlebigen Objekten. Melden Sie Listener ab in onPause/onDestroy für Android und deinit für iOS. Vermeiden Sie große statische Sammlungen — wenn nötig, verwenden Sie LruCache mit Größenbeschränkung. Optimieren Sie Bitmaps: Laden Sie Bilder mit dem richtigen inSampleSize, verwenden Sie Glide oder Picasso mit Festplatten-Cache.

Speicherprofilerstellung während der Entwicklung

Integrieren Sie die regelmäßige Heap-Dump-Erfassung in Ihre CI-Pipeline. Richten Sie eine Aufgabe ein, die instrumentierte UI-Tests ausführt, wichtige Benutzerszenarien durchführt und den Heap-Dump mit einer Basislinie vergleicht. Wenn die Retained Size um mehr als 5% gegenüber der Basislinie steigt, wird der Build als Regression markiert. Dieser Ansatz wird bei Airbnb, Uber und anderen Unternehmen mit hohen Qualitätsanforderungen praktiziert. Laut Uber Engineering reduzierte die Implementierung der automatischen Heap-Dump-Analyse in CI speicherbezogene Fehler in einem Quartal um 70%.

groovy
// Beispiel einer Gradle-Aufgabe für automatischen Heap-Dump in CI
task profileMemory(type: Exec) {
    commandLine 'adb', 'shell',
        'am start -n com.example/.MainActivity'
    // Warten auf Laden
    doLast {
        exec { commandLine 'adb', 'shell',
            'am broadcast -a com.example.DUMP_HEAP' }
    }
}

Häufig gestellte Fragen

Was ist der Unterschied zwischen Shallow Size und Retained Size?

Shallow Size ist die Größe des Objekts selbst (Felder + Header). Retained Size ist die Größe des Objekts plus aller Objekte, die bei seiner Entfernung zu Müll würden. Die Retained Size ist der Hauptindikator für die Auswirkung eines Objekts auf den Speicherverbrauch.

Wie erstellt man einen Heap-Dump auf einem physischen Android-Gerät?

Über den Android Studio Profiler wählen Sie Gerät und Prozess aus, klicken auf Dump Java Heap. Alternativ über die Befehlszeile: adb shell am dumpheap PID /sdcard/dump.hprof, dann adb pull.

Warum kann ein Heap-Dump riesig sein (500 MB+)?

Ein Heap-Dump enthält alle lebenden Objekte. Wenn die App Caches, Bitmaps oder große Datenmengen verwendet, kann der Dump hunderte Megabyte erreichen. Filtern Sie nach Klassen oder verwenden Sie Eclipse MAT, um nur den Index zu laden.

Kann man einen Heap-Dump ohne Android Studio analysieren?

Ja, verwenden Sie Eclipse MAT (Memory Analyzer Tool) — ein kostenloses Werkzeug zur Analyse von .hprof-Dateien. Es unterstützt Dominator Tree, Path to GC Roots, Dump-Vergleich und automatische Leckerkennung über den Leak Suspects Report.

Beeinträchtigt ein Heap-Dump die App-Leistung?

Der Dump selbst — ja, weil die Dump-Erfassung alle Threads anhält (Stop-the-World). Ohne Dump — nein. Erstellen Sie Dumps in kontrollierten Umgebungen (Testumgebung, CI), nicht in der Produktion.

Zusammenfassung

  • Heap Dump ist eine vollständige Momentaufnahme des Anwendungs-Heaps mit Informationen über jedes Objekt und die Beziehungen zwischen ihnen.
  • Android Studio Memory Profiler und Xcode Instruments Allocations sind die primären Dump-Erfassungswerkzeuge.
  • Shallow Size ist die Größe des Objekts selbst; Retained Size ist die Größe des Objekts mit seinem gesamten Abhängigkeits-Subgraphen.
  • Dominator Tree zeigt Objekte, die den meisten Speicher kontrollieren.
  • Path to GC Roots ist die Kette starker Referenzen, die ein Objekt von der Garbage Collection abhält.
  • Der Vergleich zweier Heap-Dumps (vor/nach einer Aktion) ist die zuverlässigste Methode zur Leckerkennung.
  • Die Automatisierung der Heap-Dump-Erfassung und -Analyse in CI verhindert Speicherregressionen während der Entwicklung.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch