JavaScript & React Memory Leaks
A memory leak occurs when memory allocated by an application is no longer needed by the program logic but is retained by unintended references, preventing Garbage Collection (GC) from reclaiming it.
Why it matters in interviews
Visual & Interactive Explanation
1. Baseline Snapshot
Take Heap Snapshot 1 in clean initial state
2. Trigger Lifecycle Flow
Open and close the suspected leaky modal/page 5 times
3. Force Garbage Collection
Click trash icon in DevTools to force Mark-and-Sweep
4. Comparison Snapshot
Take Snapshot 2 and select 'Objects allocated between Snapshots 1 & 2'
5. Inspect Retainers
Find 'Detached HTMLDivElement' and trace the retaining closure
Code Examples & Implementation
// ❌ LEAKY CODE: Timer & window listener never cleaned up
function LeakyComponent() {
useEffect(() => {
const timer = setInterval(() => console.log('Tick'), 1000);
window.addEventListener('resize', () => console.log('Resized'));
// Missing return cleanup function!
}, []);
return <div>Leaking...</div>;
}
// ✅ LEAK-PROOF CODE: Explicit cleanup + AbortSignal
function SafeComponent() {
useEffect(() => {
const abortCtrl = new AbortController();
const timer = setInterval(() => console.log('Tick'), 1000);
window.addEventListener('resize', () => console.log('Resized'), {
signal: abortCtrl.signal,
});
return () => {
clearInterval(timer);
abortCtrl.abort(); // Auto-removes all event listeners on this signal!
};
}, []);
return <div>Safe & Clean</div>;
}Interview-Ready Answers
Memory leaks happen when unreachable objects are unintentionally referenced. Common causes: uncleaned setIntervals, dangling event listeners on window/document, detached DOM elements, and uncleared WebSocket/RxJS subscriptions.
Official Documentation & Specifications
Follow-up Questions & Deep Dives
🎯 Code Output — What Does This Print?
function createLeak() {
const hugeArray = new Array(1000000).fill("x");
return function() {
console.log(hugeArray.length);
};
}
const leak = createLeak();
// Is hugeArray garbage collected?
leak();let counter = 0;
const id = setInterval(() => {
counter++;
console.log(counter);
if (counter >= 3) {
clearInterval(id);
}
}, 100);
// What prints after ~350ms?const elements = [];
function addElement() {
const div = document.createElement("div");
elements.push(div);
document.body.appendChild(div);
}
addElement();
addElement();
document.body.innerHTML = "";
console.log(elements.length);
// Are the div elements garbage collected?Common Mistakes & Anti-Patterns
- Assuming modern garbage collectors automatically clean up setInterval or window event listeners
- Storing large data collections in global window variables or module-level arrays
- Retaining references to unmounted React components inside third-party charting libraries
Real-World Architectural Scenario
A trading dashboard runs 24/7. After 4 hours, Chrome tab memory grows from 80MB to 1.8GB and begins stuttering. What is your diagnosis process?
Rate Your Readiness
Rate how comfortably you can explain this in an interview to update your global readiness gauge: