Kurze Antwort
Ein Speicherleck entsteht, wenn eine Anwendung Speicher belegt und ihn nach der Nutzung nicht freigibt. Es zeigt sich durch ständig steigenden Speicherverbrauch und Verlangsamung. Es wird mit Speicherüberwachungstools und Codeanalyse erkannt und durch Beseitigung der Ursache behoben, meist durch vergessene Referenzen.
So erkennen Sie das Problem
- Der Speicherverbrauch der Anwendung steigt während des Betriebs ständig an
- Die Anwendung wird mit der Zeit langsamer und instabil
- Das Programm stürzt mit einem Fehler wegen Speichermangels ab
- Das Betriebssystem beginnt, Swap zu verwenden, und wird träge
Häufigste Ursachen
Vergessene Referenzen
Objekte bleiben im Speicher, weil eine Referenz weiterhin auf sie zeigt, obwohl sie nicht mehr benötigt werden. Das ist die häufigste Ursache für Lecks.
Nicht entfernte Event-Listener
Listener und Callback-Funktionen, die hinzugefügt, aber nicht entfernt werden, halten Objekte im Speicher. Besonders häufig in langlebigen Anwendungen.
Caches ohne Begrenzung
Ein Cache, der unbegrenzt wächst oder keine Eintragsablaufzeit hat, belegt mit der Zeit den gesamten verfügbaren Speicher. Dasselbe gilt für globale Sammlungen.
Referenzzyklen
Objekte, die sich gegenseitig referenzieren, können im Speicher bleiben, wenn der Garbage Collector sie nicht bereinigen kann. In Sprachen und Umgebungen mit Referenzzählung sind Zyklen eine häufige Leckursache.
Lösung Schritt für Schritt
- 1
Bestätigen Sie, dass ein Leck vorliegt
Starten Sie die Anwendung und überwachen Sie den Speicherverbrauch über den Task-Manager (Windows) oder den Aktivitätsmonitor (macOS). Wenn der Speicher mit der Zeit steigt und nach Abschluss der Vorgänge nicht sinkt, liegt wahrscheinlich ein Leck vor. Notieren Sie den Ausgangswert und wiederholen Sie dieselbe Aktion mehrmals.
- 2
Isolieren Sie das Szenario, das den Anstieg verursacht
Wiederholen Sie jeweils eine Funktionalität (Öffnen eines Bildschirms, Laden von Daten, Senden von Anfragen) und beobachten Sie den Speicher. Ziel ist es, die kleinste Schrittfolge zu finden, die einen ständigen Anstieg verursacht. Notieren Sie die Schritte, damit Sie sie später wiederholen können.
- 3
Verwenden Sie ein Speicherüberwachungstool
Öffnen Sie im Browser die DevTools > Memory und erstellen Sie einen Heap-Snapshot vor und nach der verdächtigen Aktion. Vergleichen Sie die Snapshots und suchen Sie nach Objekten, die bleiben. In Node.js verwenden Sie
node --inspectund die Chrome DevTools, in .NET die Visual Studio Diagnostic Tools. - 4
Analysieren Sie den Heap-Snapshot
Sehen Sie sich im Tool die Liste der Objekte an, sortiert nach Größe oder Anzahl der Instanzen. Achten Sie auf Objekte, die entfernt werden sollten. Verfolgen Sie die Referenzketten (Retainer), um zu sehen, was das Objekt im Speicher hält.
- 5
Prüfen Sie Event-Listener und Timer
Durchsuchen Sie den Code nach Stellen, an denen Sie Listener hinzufügen (
addEventListener,on,subscribe), und prüfen Sie, ob Sie sie entfernen (removeEventListener,off,unsubscribe). Dasselbe gilt fürsetIntervalundsetTimeout, die mitclearIntervalundclearTimeoutgestoppt werden sollten, wenn sie nicht mehr benötigt werden. - 6
Begrenzen Sie Caches und Sammlungen
Verwenden Sie für Caches eine Größenbeschränkung oder eine Ablaufzeit (z. B. LRU-Cache). Vermeiden Sie globale Arrays und Maps, die unkontrolliert wachsen. Bereinigen Sie regelmäßig alte Einträge.
- 7
Beseitigen Sie die Ursache und testen Sie
Nachdem Sie die Ursache gefunden haben, ändern Sie den Code so, dass die Referenzen freigegeben werden. Wiederholen Sie denselben Test und überwachen Sie den Speicher: Er sollte stabil bleiben. Fügen Sie bei Bedarf einen automatischen Test hinzu, der prüft, dass der Speicher nicht wächst.
Wenn nichts hilft
Wenn Sie die Ursache nicht finden können, erwägen Sie, den verdächtigen Codeabschnitt zu vereinfachen und erneut zu testen. Manchmal stammt das Leck aus einer Bibliothek eines Drittanbieters; prüfen Sie, ob sie aktualisiert wurde und ob das Problem bekannt ist. Überwachen Sie in der Produktion den Speicher mit Monitoring-Tools und richten Sie einen Alarm ein, wenn der Verbrauch einen Grenzwert überschreitet. Verwenden Sie für komplexe Fälle fortgeschrittene Tools wie Heap-Profiler und Tools zur Analyse von Allokationen. Wenn das Leck nur unter Last auftritt, testen Sie mit einer Simulation mehrerer Benutzer.
So beugen Sie vor
- Überprüfen Sie den Code regelmäßig auf Stellen, an denen Listener und Timer hinzugefügt werden
- Verwenden Sie begrenzte Caches und bereinigen Sie Sammlungen
- Testen Sie den Speicher vor der Produktionsfreigabe
- Überwachen Sie den Speicherverbrauch in der Produktion
Wann Sie einen Profi rufen sollten
Wenn das Leck in der Produktion Abstürze verursacht oder Sie es nicht reproduzieren können, wenden Sie sich an den IT-Support oder einen erfahreneren Entwickler zur Analyse.
Software- und Produktentwicklung · Individuelle Apps, SaaS und ein MVP in 4 bis 8 WochenHäufige Fragen
Wie erkenne ich, ob die Anwendung ein Speicherleck hat oder nur anspruchsvoll ist?
Wenn der Speicher während des Betriebs konstant steigt und nach Abschluss der Vorgänge nicht freigegeben wird, liegt wahrscheinlich ein Leck vor. Eine anspruchsvolle Anwendung kann mehr Speicher verwenden, sollte ihn aber freigeben, wenn er nicht mehr benötigt wird.
Ist ein Speicherleck sicherheitsrelevant?
Es kann sein. Ein Leck kann zu Ressourcenerschöpfung und Systemausfall führen, was Angreifer für Denial-of-Service (DoS) ausnutzen können. Außerdem kann Speicher mit sensiblen Daten länger verfügbar bleiben, was das Risiko von Informationslecks erhöht.
Wie oft sollte der Speicher überprüft werden?
Es wird empfohlen, bei jeder größeren Änderung und regelmäßig in der Produktion zu prüfen. Automatisierte Tests können helfen, ein Leck frühzeitig zu erkennen.