4

I think I am just missing something basic. I dont understand the how memory is being allocated. If I just hit this function over and over again, it leaks like crazy (just watching it grow in top). I am new to nodejs and javascript in general. I can't seem to find any explanation why this is wrong, but it is wrong.. Is it how I am calling handleMessage by using the require statement inline? I also tried setting a variable equal to the require statement and just accessed that variable but it still kept eating memory. Anything will be a big help!

main.js:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  if (req.url == "/getRandom")
  {
    require('./getRandom.js').handleMessage(req,res)
  }
  else
  {
    res.end(req.url+'\n');
  }
}).listen(443);
console.log('Server running at http://127.0.0.1:443/');

getRandom.js:

var qs = require('querystring');
function getRandom()
{
    var numbers = new Array()
    for (i = 0; i < 100; i++)
    {
            numbers[i] = Math.floor(Math.random()*100);
    }
    return numbers;
}
function handleMessage(req,res)
{
    var body = '';
    req.on('data', function (data) {
        body += data;
    });
    req.on('end', function () {
            var t = JSON.parse(body);
            var c = t.name;
            var response = new Object();
            response.numbers = getRandom();
            res.end (JSON.stringify(response));
            response.numbers = null;
            response = null;
            body=null;
            t=null;
    });
}
module.exports.handleMessage = handleMessage;
  • I suspect that the memory leak comes from you creating a new array every time you call the function, while the garbage collector is unsure when it is safe to clean it up again - [this may help you solve this problem](http://stackoverflow.com/questions/5733665/how-to-prevent-memory-leaks-in-node-js) – UnholySheep Oct 23 '13 at 18:54

1 Answers1

1

Memory is allocated for the numbers Array, but I don't see any memory leak here. Garbage collector does not have to run as soon as there is something to claim back.

To illustrate my point, if you will increase length of the Array to help GC start collecting memory faster (also some minor tweaks)

function getRandom()
{
  var numbers = new Array()
  for (var i = 0; i < 100000; i++)
  {
    numbers[i] = Math.floor(Math.random()*100);
  }
  return numbers;
}
function handleMessage(req,res)
{
  var body = '';
  req.on('data', function (data) {
    body += data;
  });
  req.on('end', function () {
    var response = new Object();
    response.numbers = getRandom();
    res.end (JSON.stringify(response));
    response.numbers = null;
    response = null;
  });
}
module.exports.handleMessage = handleMessage; 

memory will be freed faster, so it's actually will be noticeable.

Here is screenshot from Instruments on OSX, when running the code mentioned above, executing 60 requests per second to /getRandom endpoint

enter image description here

In top output, it's noticable that RSIZ - (Resident memory size) goes up and down (when memory is allocated, and then - freed)

Andrzej Karpuszonak
  • 8,896
  • 2
  • 38
  • 50
  • Thanks! I think I was just impatient and unsure of how javascript handles things. I believe this to be correct - I was just not waiting long enough for GC to kick in. – user1695632 Oct 25 '13 at 15:33
  • Does it really change something to do: response.numbers = null; response = null instead of doing only response = null; ? – Unitech Aug 13 '14 at 00:27