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++:
mallocohnefree, 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 * xAuffinden
- 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