EMZETT.
Login

Speicherleck (Memory Leak)

Kurz: Ein Speicherleck liegt vor, wenn ein Programm Speicher belegt und nach Gebrauch nicht wieder freigibt. Der Speicherverbrauch wächst unaufhörlich, bis das Programm langsam wird oder abstürzt.

Genauer: In Sprachen mit manueller Speicherverwaltung (C, C++) entsteht ein Leck, wenn man free/delete vergisst. Auch in Sprachen mit Garbage Collector sind Lecks möglich: Der GC räumt nur auf, was nicht mehr erreichbar ist. Hält eine vergessene Referenz ein Objekt fest, bleibt es im Speicher.

Im Detail

Typische Ursachen

  • C/C++: malloc ohne free, Fehlerpfade, die den Aufräumcode überspringen.
  • Wachsende Caches ohne Obergrenze (siehe Memoization).
  • Nicht entfernte Listener/Callbacks: Ein Objekt, das sich bei einem Subjekt anmeldet (Observer-Muster) und nie abmeldet, wird nie freigegeben.
  • Globale Sammlungen, in die ständig Elemente gelangen, aber nie herausgenommen werden.
  • Nicht geschlossene Ressourcen wie Dateien, Datenbankverbindungen und Sockets (close, with, try-with-resources).
cache = {}
 
def verarbeite(anfrage_id, daten):
    cache[anfrage_id] = daten          # wächst bei jeder neuen Anfrage, nie bereinigt!
    return len(daten)
 
# besser: begrenzter Cache
from functools import lru_cache
 
@lru_cache(maxsize=1000)
def berechne(x):
    return x * x

Auffinden

  • Speicherverbrauch über die Zeit beobachten (Task-Manager, top, Metriken).
  • Valgrind, AddressSanitizer (C/C++), Heap-Dumps und Profiler (Java: VisualVM, JProfiler; Python: tracemalloc; Chrome DevTools: Memory).
  • Moderne Sprachen helfen: Rust verhindert Lecks meist durch sein Besitzmodell, C++ durch Smart Pointer, Python/Java durch automatische Verwaltung.

Mehr zu den Strategien der Speicherverwaltung steht im Artikel Speicherverwaltung.

Siehe auch: Garbage Collector, Stack und Heap, Zeiger, try-with-resources