zztczcx
zztczcx

Reputation: 430

nodejs memory leak in several cases

  1. the raw native tcp server I used a client test code to concurrent long connect the server, and do nothing。 After 5w conncetions I shut down the client.js, but the server side will have about 100M memory don't release.

the server code :

var net = require('net');
var server = net.createServer(function(client) {
  console.log('server connected');
  client.on('data',function(){});
  client.on('end',function(){console.log('end');});

});
server.listen(8124, function() {
  console.log('server bound');
});

the client code:

var net = require('net');
var host = '192.168.0.110'
// var host = "localhost"
  , port = 8124


for(var i=0; i < 50000; i++){
  var client = net.connect({host: host, port: port},
      function(i){
       return function() { //'connect' listener
           var num = i;
           console.log('client connected ' + num);
      }}(i)
  );
  client.on('end',function(){
        console.log('end');
        client.end()
  })
}

the client is on another machine

2, long loop

 var a = b = c = d = [];
 console.log((process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), 'Mb');

 for(i=0;i<50000;i++){
     a.push(new Date());
     b.push(new Date());
     c.push(new Date());
     d.push(new Date());

 }
 console.log((process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), 'Mb');
   a = null;
   b = null;
   c = null;
   d = null;

 console.log('null');
 console.log((process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), 'Mb');

 console.log((process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), 'Mb');
 setInterval(function(){
   console.log((process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), 'Mb');
 },5000);

I set the variable to null but the memory does not release. somebody tell me to use process.nextTick to prevent long loop but it still doesn't work.

Upvotes: 2

Views: 1573

Answers (2)

Esailija
Esailija

Reputation: 140236

There is a problem with your client js:

client.on('end', function() {
    console.log('end');
    client.end()
})

This event will happen after the connection ends, which you do by calling .end()... so it doesn't make any sense to call .end() in the end event. Also, you are not closing the connection at all:

var client = net.connect({
    host: host,
    port: port
}, function(i) {
    return function() { //'connect' listener
        var num = i;
        console.log('client connected ' + num);
        this.end() //Close the connection
    }
}(i));

After fixing that I can run your code without exceptions, and it did not leak for me.

Server code:

function getUsed() {
    return process.memoryUsage().heapUsed;
}
var startedWith;
var net = require('net');
var server = net.createServer(function(client) {
    client.on('data', function() {});
    client.on('end', function() {
        console.log("end");
    });
});
server.listen(8124, function() {
    startedWith = getUsed();
});
setInterval(function() {
    gc();
}, 13);
setInterval(function() {
    gc();
    console.log(getUsed() - startedWith);
}, 250)

Run with node 0.10 $ node --expose-gc server.js

Client code:

var net = require('net');
var host = 'localhost',
    port = 8124
for (var i = 0; i < 1500; i++) {
    var client = net.connect({
        host: host,
        port: port
    },

    function(i) {
        return function() { //'connect' listener
            var num = i;
            console.log('client connected ' + num);
            this.end();
        }
    }(i));
    client.on('end', function() {
        console.log('end');
    })
}

Run with node 0.10 $ node client.js after server is running.

Upvotes: 0

Andrei Karpuszonak
Andrei Karpuszonak

Reputation: 9044

Memory is not released immediately after you deallocate the reference and set it to null. If you want to force GC to be executed in a given moment:

  1. start node with --expose-gc

node --expose-gc test.js

  1. in your code add invocation of gc:

global.gc();

You shall not do this in production, as V8 is handling GC invocation by itself and is very good in it.

Upvotes: 2

Related Questions