Detecting Memory Leaks in Node.js

Dara Hayes

dara.hayes@redhat.com

@darahayess

@darahayes

That's me!

Let's talk about V8

Resident Set

Code

Stack

Pointers, Primitive types

Heap

Objects, Strings, Closures

Used Heap

V8 Memory Scheme

process.memoryUsage()

{ 
  rss: 21561344,
  heapTotal: 10522624,
  heapUsed: 4110504
}

Garbage Collection

Heap

Young Space (1-8MB)

Young Space and Old Space in V8 Heap

Old Space

New allocations

Scavenge Garbage Collection

More Frequent, Much Faster GCs

Objects that Survived 2 GCs in Young Space

 Mark-Sweep Collection

Less Frequent, Pauses All JS Execution

Scavenge GC

Mark-Sweep GC

node --trace-gc index.js

Let's find a memory leak

aka demo time :)

const http = require('http')

const server = http.createServer((req, res) => {
 for (var i=0; i<1000; i++) {
   server.on('request', function leakyfunc() {})
 }

 res.end('Hello World\n')
}).listen(1337, '127.0.0.1')

server.setMaxListeners(0)

1. Create heap dumps at different time intervals

2. Compare the dumps to see growth areas

It's so Simple!

Tools We Can Use

npm.im/memwatch-next

npm.im/heapdump

--inspect or (npm.im/node-inspector)

--trace-gc

--expose-gc

and more...

const memwatch = require('memwatch-next')

memwatch.on('leak', function (info) {
  console.log('Memory leak detected:\n', info)
})

‘A leak event will be emitted when your heap usage has increased for five consecutive garbage collections.’

A fork of the outdated memwatch module.

Last published 2 years ago but it works on Node 8.

--inspect

Debug your node process in Chrome dev tools

Create heap dumps

Only available in Node v6+

Otherwise use npm.im/node-inspector

const heapdump = require('heapdump')

heapdump.writeSnapshot((err, filename) => {
  if (err) console.error(err)
  else console.log('Wrote snapshot: ' + filename)
})

Snapshots can be opened in dev tools.

Can be triggered by sending SIGUSR2 signal.

demo
Are there low level tools out there?

Take Core Dumps of Your Node Process

--abort-on-uncaught-exception 
# Create a core dump when process crashes
gcore <pid> 
# Low level tool to create dumps

Inspect Core Dumps with Low Level Debugging Tools

Things to Consider

  • Snapshots are expensive on CPU and Memory.

  • Try to find leaks in a test environment

  • If using something like memwatch in prod, make sure leaks are picked up by alerting tools

  • Consider other ways of tracking memory e.g. process.memoryUsage()

  • Beware of false positives

end ☕️

Notes

Detecting Memory Leaks in Node.js

By Dara Hayes

Detecting Memory Leaks in Node.js

This slide deck demonstrates approaches to finding memory leaks in Node.js. Topics covered include memory management and garbage collection in v8, and tooling used to find memory leaks.

  • 3,582