Memory Leak Detection & Heap Snapshots0%

Memory Leak Detection & Heap Snapshots

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Memory Leak Detection & Heap Snapshots in Modern JavaScript

In long-running Single Page Applications (SPAs) and Node.js microservices, unresolved memory allocations degrade application speed and eventually crash the browser tab or server with an Out of Memory error. Profiling the V8 Heap and analyzing Heap Snapshots in Chrome DevTools is essential for senior engineers.


1. Common Causes of JavaScript Memory Leaks

1. Detached DOM Elements

An element is removed from the DOM tree, but a JavaScript reference still points to it in a variable or array:

JavaScript
// DANGER: Detached DOM Leak
const elementCache = [];
 
function removeButton() {
const btn = document.querySelector('#btn-leak');
elementCache.push(btn); // Retaining reference in array!
btn.remove(); // Removed from DOM tree, BUT CANNOT BE GARBAGE COLLECTED!
}

2. Forgotten Timers & Callbacks

JavaScript
// Timer callback retains 'largeData' in its closure indefinitely!
const largeData = new Array(1000000).fill('leak');
setInterval(() => {
console.log('Heartbeat...');
}, 1000); // If never clearInterval(), largeData may stay in memory!

3. Accidental Global Variables

In non-strict mode, assigning to an undeclared variable attaches it to window, preventing garbage collection:

JavaScript
function leakGlobal() {
leakedData = new Array(1000000); // window.leakedData (Never freed!)
}

2. Taking & Comparing Heap Snapshots

  1. 1
    Open DevTools -> Memory tab.
  2. 2
    Select Heap snapshot -> Click Take snapshot.
  3. 3
    Perform the suspicious action (e.g. open modal and close it 10 times).
  4. 4
    Take Snapshot 2.
  5. 5
    Change view dropdown from Summary to Comparison between Snapshot 1 and Snapshot 2.
Output
DevTools Memory Panel:
[ Snapshot 1: 14.2 MB ]
│ (User opens & closes modal 5 times)
[ Snapshot 2: 38.6 MB ] ──► +24.4 MB Delta! (Clear Memory Leak!)

3. Interpreting Retainers and Shallow vs. Retained Size

In the Memory Inspector:

  • Shallow Size: The memory directly held by the object itself (typically small, e.g. 32 bytes for the pointer map).
  • Retained Size: The total memory freed if this object is deleted (includes all referenced child objects and buffers).
  • Retainer Tree: The path of references keeping the object alive from the GC Root (window / global).
Output
GC Root (window)
└── appState
└── listeners[]
└── modalElement (Detached HTMLDivElement) ◄── Identifies Retainer!

4. Best Practices to Prevent Leaks

  1. 1
    Unregister Listeners: Always detach listeners when DOM elements are unmounted (removeEventListener or AbortController).
  2. 2
    Use WeakRef & WeakMap: Weak collections allow keys to be garbage-collected if no other references exist.
  3. 3
    Nullify Large Buffers: Explicitly set large arrays or buffers to null once processing is complete.

Interactive Quiz

Practice Quiz

Question 1
What is a "Detached DOM Tree" in memory profiling?
Question 2
What is the difference between "Shallow Size" and "Retained Size" in a Heap Snapshot?
Question 3
How do you identify which variable is keeping an object alive in a Heap Snapshot?
Question 4
Why can setInterval cause memory leaks if not cleared?
Question 5
What collection type should you use to store metadata about DOM elements without preventing their garbage collection?
Next Lesson

Source Maps & Production Debugging

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext