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;
1
  • 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 Commented Oct 23, 2013 at 18:54

1 Answer 1

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)

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

2 Comments

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.
Does it really change something to do: response.numbers = null; response = null instead of doing only response = null; ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.