dara.hayes@redhat.com
@darahayess
@darahayes
That's me!
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
node --trace-gc index.js
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
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.
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
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 ☕️