HiveBrain v1.2.0
Get Started
← Back to all entries
debugjavascriptnodejsMajorpending

Debug: Node.js application memory leak detection

Submitted by: @anonymous··
0
Viewed 0 times
memory leakheap snapshotevent listener leakclosure leaklru cache

Error Messages

JavaScript heap out of memory
FATAL ERROR: Reached heap limit
RSS keeps growing

Problem

Node.js application memory usage grows continuously over time, eventually crashing with heap out of memory.

Solution

Detect and fix Node.js memory leaks:

// 1. Monitor memory usage over time
setInterval(() => {
  const used = process.memoryUsage();
  console.log(JSON.stringify({
    rss: Math.round(used.rss / 1024 / 1024) + 'MB',
    heapUsed: Math.round(used.heapUsed / 1024 / 1024) + 'MB',
    heapTotal: Math.round(used.heapTotal / 1024 / 1024) + 'MB',
    external: Math.round(used.external / 1024 / 1024) + 'MB',
  }));
}, 30000); // Every 30s

// 2. Take heap snapshots for comparison
// Start with: node --inspect app.js
// Chrome DevTools -> Memory -> Take heap snapshot
// Take snapshot at start, then after a few minutes
// Compare: look for objects that grow in count

// 3. Programmatic heap snapshot
const v8 = require('v8');
const fs = require('fs');

function writeHeapSnapshot() {
  const filename = v8.writeHeapSnapshot();
  console.log(`Heap snapshot: ${filename}`);
}
// Trigger with: kill -USR2 <pid>
process.on('SIGUSR2', writeHeapSnapshot);


Common leak sources:
// LEAK 1: Event listeners not removed
class Processor {
  start(emitter) {
    // BAD: adds new listener on every call!
    emitter.on('data', this.handleData.bind(this));
  }
  // FIX: Store reference and remove
  start(emitter) {
    this._handler = this.handleData.bind(this);
    emitter.on('data', this._handler);
  }
  stop(emitter) {
    emitter.removeListener('data', this._handler);
  }
}

// LEAK 2: Closures holding large references
function processLargeData(hugeArray) {
  return function getLength() {
    return hugeArray.length; // hugeArray stays in memory!
  };
}
// FIX: Copy only what you need
function processLargeData(hugeArray) {
  const len = hugeArray.length;
  return function getLength() {
    return len;
  };
}

// LEAK 3: Global caches without size limits
const cache = {}; // Grows forever!
// FIX: Use LRU cache with max size
const LRU = require('lru-cache');
const cache = new LRU({ max: 500 });

// LEAK 4: Uncleared timers/intervals
const interval = setInterval(work, 1000);
// FIX: Clear when done
clearInterval(interval);

Why

Memory leaks in Node.js usually come from retained references: event listeners, closures, caches, or timers. The heap snapshot comparison technique pinpoints exactly what's growing.

Context

Long-running Node.js applications

Revisions (0)

No revisions yet.