2

I have some code in a library that has in the past leaked badly, and I would like to add regression tests to avoid that in the future. I understand how to find memory leaks manually, by looking at memory usage profiles or Valgrind, but I have had trouble writing automatic tests for them.

I tried using global.gc() followed by process.memoryUsage() after running the operation I was checking for leaks, then doing this repeatedly to try to establish a linear relationship between number of operations and memory usage, but there seems to be noise in the memory usage numbers that makes this hard to measure accurately.

So, my question is this: is there an effective way to write a test in Node that consistently passes when an operation leaks memory, and fails when it does not leak memory?

One wrinkle that I should mention is that the memory leaks were occurring in a C++ addon, and some of the leaked memory was not managed by the Node VM, so I was measuring process.memoryUsage().rss.

2 Answers 2

3
+25

Automating and logging information to test for memory leaks in node js.

  • There is a great module called memwatch-next.

    npm install --save memwatch-next

Add to app.js:

const memwatch = require('memwatch-next'); // ... memwatch.on('leak', (info) => { // Some logging code... console.error('Memory leak detected:\n', info); }); 

This will allow you to automatically measure if there is a memory leak.

  • Now to put it to a test:

Good tool for this is Apache jMeter. More information here.

If you are using http you can use jMeter to soak test the application's end points.

SOAK testing is done to verify system's stability and performance characteristics over an extended period of time, its good when you are looking for memory leaks, connection leaks etc.

  • Continuous integration software:

Prior to deployment to production if you are using a software for continuous integration like Jenkins, you can make a Jenkins job to do this for you, it will test the application with parameters provided after the test will ether deploy the application or report that there is a memory leak. ( Depending on your Jenkins job configuration )

Hope it helps, update me on how it goes;

Good luck,

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the information about this library, but I don't think it helps with my specific scenario. I tried using it with a test that I was sure would qualify as a leak (creating and starting servers bound to different ports in a loop), and the memwatch event never fired.
Mem watch is on the level of the application as such every server you start will have its own mem. watch for that instance it will be oblivious to the global picture that is the process that is spawning servers. You can use containers for such actions forever and forever-monitor, where you have full control over node process and overview of memory,
0

Given some arbitrary program, is it always possible to determine if it will ever terminate? The halting problem describes this. Consider the following program:

function collatz(n){ if(n==1) return; if(n%2==0) return collatz(n/2); else return collatz(3*n+1); } 

The same idea can be applied to data in memory. It's not always possible to identify what memory isn't needed anymore and can thus be garbage collected. There is also the case of the program being designed to consume a lot of memory in some situation. The only known option is coming up with some heuristic like you have done, but it will most likely result in false positives and negatives. It may be easier to determine the root cause of the leak so it can be corrected.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.