In last week’s performance tip, we discussed in detail how to leverage Google V8’s heap profiler to diagnose problems with Node applications. In this go around we look at different leak patterns and how a good diagnosis can lead us to find the root cause of a potentially troublesome production problem.
Rapid memory leaks are easy to identify and often the cause of many memory issues. Node by itself is very sensitive to errors and exceptions and will crash due to out of memory exceptions. Slow leaks are the most difficult to find and often require profiling over long periods of time to properly identify.
Slow memory leak pattern
Rapid memory leak pattern
Profiling by itself provides isolation up to type and count of objects in the heap and in retainers. We provide that in StrongOps; however to get down to the line of code, you need deeper inspection.
Client Side Heapdumps : Chrome Dev Tools
Server Side Heap Snapshots: Triggered, Timed, Thresholded
Server side heap snapshots are needed during analysis in higher environments like performance testing, UAT or production. These snapshots can be collected using the Node heapdump module written by StrongLoop founder, Ben Noordhuis.
npm install heapdump
This module helps gather server side heap dumps under production load using 3 techniques – User issued SIG commands, Timer based programmatic and Memory Threshold based programmatic. More details available on this Node Heap Snapshots blog.
Let’s conduct a mock exercise by forcing a memory leak. Include the heapdump module into a leaky class called ChocolateClass that simply adds 100 units of objects every second into an array – sugar.
Running this application and taking heap-snapshots using the Kill -USR2 <pid> commands gives us two heapdumps to inspect side by side.
Now we can load these into Chrome Dev Tools for visual inspection.
We sorted the first heap snapshot by object count and found that the ChocolateClass was the top memory utilizer with 37% of the objects in heap. But this is not enough evidence to conclusively prove anything. We can see some retainers at higher levels for other types of objects too.
Inspecting the second heap snapshot taken on the server after a delay of 1 minute from the first one, confirmed our suspicions. We can see that the ChocolateClass has suddenly bloated in heap consumption to about 77% of the heap size. The shallow and retainer sizes of this class is now close to 30% of overall.
Drilling down into the ChocolateClass, we see it’s the sugar array which is causing all this bloating. We can even inspect the call path, the data elements and attributes and all the objects in depth. Retaining paths are actually any paths that link objects with GC roots. Path inspection is critical here.
Interestingly, we can see that there are nearly 47K sugar units in the array and the array is not being garbage collected properly.
Understanding some basic memory constructs in Node.js
Use StrongOps to Monitor Node Apps
Ready to start monitoring event loops, manage Node clusters and chase down memory leaks? We’ve made it easy to get started with StrongOps either locally or on your favorite cloud, with a simple npm install.
- What’s in the upcoming Node v0.12 release? Big performance optimizations! Read Ben Noordhuis’ blog to learn more.
- Watch Bert Belder’s comprehensive video presentation on all the new upcoming features in v0.12
- Ready to develop APIs in Node.js and get them connected to your data? We’ve made it easy to get started either locally or on your favorite cloud, with a simple npm install.