Updated and republished by Dara Hayes on May 24 2017 Tracking down memory leaks with Node.js has always been a challenge. The following discusses how to track memory leaks in a Node application using Nodes
--inspect flag and the two awesome node modules memwatch and heapdump .
First, a trivial sample leak:
Every request adds another 1,000 leaky listeners. We are going to simulate requests using autocannon – A HTTP benchmarking tool written in node. It can be installed with
npm i -g autocannon . If we run
autocannon -c 1 -d 60 https://localhost:1337 in one shell, and in another shell view our process:
top -pid we will see very high and erratic memory usage for this node process. Our node process has gone wild. So how do you diagnose from here?
The memwatch-next module is great for detecting memory leaks. Lets install into our app as follows:
npm install --save memwatch-next . Then, in our code, add:
and also a listener for the leak event:
Now when we run our test again, we see the following emitted:
Memwatch has detected a memory leak! Memwatch defines a leak event as:
So weve detected that we have a memory leak great! But what now? The next step is to find where your leak is. The example leak is pretty obvious, but the process for finding one is always the same:
Lets see two ways of doing this.
--inspect flag landed in node version 6. This feature lets you debug and inspect your node process from within Chromes DevTools . Simply start the application passing the
Follow the URL to the inspector and navigate to the memory tab.
DevTools Memory Tab Heres what we will do:
Heap Snapshot Comparison The comparison view shows us what has happened between snapshots. We can see a huge number of closure objects have been created. The delta columns also give us an idea of how much growth there has been. Lets take a deeper look:
Found our Memory Leak Now it is clear that our
leakyfunc() is the root of the problem. The Retainers view shows where the reference to our
leakyfunc() object is held in memory. We can also find exactly where it was created in our code.
node-heapdump is a great module. If the
--inspect option is not available, or you need to create snapshots programmatically, heapdump can be used to create a snapshot from within the application code. For more on heapdump, see the following StrongLoop blog post . Let’s use heapdump in our code now, so that every time a memory leak is detected, we write out a snapshot of the V8 stack to disk:
Run our test again, and you should see some ‘.heapsnapshot’ files created in our application folder. Now in Chrome, launch DevTools (alt-cmd-i on Mac), hit the Memory tab and hit Load to load in our snapshots. Now we can find the leak as we did in the previous section.
The above outlines one method of ‘self detecting’ memory leaks in Node and these are my concluding observations:
The gist for source code referred to in this article can be found here . Having trouble with detecting memory leaks in node.js or want to know more on self-detection of memory leaks? You can tweet me or connect with me on LinkedIn .
If you’d like to know more about how NearForm can help you, contact us here