Common JavaScript Memory Leaks
Common leak patterns include accidentally retained global references, event listeners that remain attached unnecessarily, timers that keep closures alive, caches that grow without bounds, and long-lived data structures retaining objects that should have been released.
Closures themselves are not memory leaks. They become problematic when a long-lived object retains a closure that in turn retains a large object graph unnecessarily.
An Unbounded Cache
const cache = new Map();
function remember(key, value) {
cache.set(key, value);
}
// If keys continuously grow and entries are never removed,
// the cache can retain more and more memory.💡 The Map itself remains reachable, so entries remain reachable through it. An unbounded cache can therefore create sustained memory growth.
Key Takeaways
- Closures are not inherently memory leaks.
- Long-lived references can retain large object graphs.
- Caches should have eviction or bounded lifetime when appropriate.
Knowledge Check
Which pattern can cause a memory leak?