2
  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.

1
  • You are trying to do the stress on server or you want to know what happened to your server if reached 50k concurrent server? What @miktam said is correct, you have to wait the GC to clear the momory. If your server really reached 50 k concurrent users, i recommend you to scale out your server to avoid memory leaks. Commented Jun 4, 2013 at 9:35

2 Answers 2

2

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.

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

Comments

0

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.

5 Comments

because you use the gc() . and have you ever try just use the setInterval()? the memory that used more and more!
@vagabond of course I use gc(), otherwise I'd have to wait longer to see results.
oh I am sorry @Esailija, I misunderstand the gc() command. yes, the v8 default gc is very inactive。
@vagabond gc() will not release memory if that memory woulnd't have been released via normal gc eventually..
thanks @Esailija do you have any more information about how v8 gc ? where do you learn the v8

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.