Debugging Memory Leaks in Node.js Applications
Introduction
Memory leaks can cause performance degradation and crashes. This tutorial covers techniques to detect, analyze, and fix memory leaks in Node.js.
Prerequisites
- Node.js >=14
Step 1: Enable Heap Snapshots
Run Node.js with the inspector:
node --inspect-brk app.js
Open Chrome DevTools > Memory tab > click Take heap snapshot.
Step 2: Analyze Heap Snapshots
- Compare snapshots over time to find growing object counts.
- Look for detached DOM trees or retained closures.
Step 3: Use Heapdump for On-Demand Snaps
Install:
npm install heapdump
In code:
const heapdump = require("heapdump");
process.on("SIGUSR2", () => {
const filename = `./${Date.now()}.heapsnapshot`;
heapdump.writeSnapshot(filename, err => {
if (err) console.error(err);
else console.log(`Heap snapshot written to ${filename}`);
});
});
Trigger snapshot:
kill -SIGUSR2 <pid>
Step 4: Monitor Real-Time Memory Usage
Use --trace-gc
flag:
node --trace-gc app.js
Logs show GC activity and memory reclaimed.
Step 5: Common Leak Patterns
- Unbounded caches
- Forgotten timers or intervals
- Global variables holding references
Step 6: Fixing Leaks
- Clear timers (
clearInterval
) - Limit cache size or use LRU
- Avoid retaining large structures in closures
Summary
Regular memory profiling and heap snapshot analysis help identify leaks early, ensuring stable and performant Node.js applications.