【问题标题】:nodejs memory leak in several casesnodejs内存泄漏的几种情况
【发布时间】:2013-05-30 08:40:35
【问题描述】:
  1. 原始原生 tcp 服务器 我用一个客户端测试代码并发长连接服务器,什么都不做。 连接 5w 后我关闭了 client.js,但是服务器端会有大约 100M 内存没有释放。

服务器代码:

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');
});

客户端代码:

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()
  })
}

客户端在另一台机器上

2、长循环

 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);

我将变量设置为空,但内存没有释放。 有人告诉我使用 process.nextTick 来防止长循环 但还是不行。

【问题讨论】:

  • 您正在尝试对服务器施加压力,或者您想知道如果达到 50k 并发服务器,您的服务器会发生什么? @miktam 说的是正确的,您必须等待 GC 清除内存。如果你的服务器真的达到了 50k 并发用户,我建议你扩展你的服务器以避免内存泄漏。

标签: javascript node.js memory v8


【解决方案1】:

在您取消分配引用并将其设置为 null 后,不会立即释放内存。如果你想强制 GC 在给定时刻执行:

  1. 使用 --expose-gc 启动节点

node --expose-gc test.js

  1. 在您的代码中添加 gc 调用:

global.gc();

你不应该在生产环境中这样做,因为 V8 自己处理 GC 调用并且非常好。

【讨论】:

    【解决方案2】:

    你的客户端js有问题:

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

    此事件将在连接结束后发生,您可以通过调用 .end()... 来完成此操作,因此在结束事件中调用 .end() 没有任何意义。此外,您根本没有关闭连接:

    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));
    

    修复后我可以毫无例外地运行您的代码,并且它没有泄漏给我。

    服务器代码:

    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)
    

    使用节点 0.10 $ node --expose-gc server.js 运行

    客户端代码:

    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');
        })
    }
    

    在服务器运行后使用节点 0.10 $ node client.js 运行。

    【讨论】:

    • 因为您使用 gc() 。你有没有试过只使用 setInterval()?使用越来越多的内存!
    • @vagabond 当然我使用gc(),否则我必须等待更长时间才能看到结果。
    • 哦,对不起@Esailija,我误解了 gc() 命令。是的,v8 默认 gc 非常不活跃。
    • @vagabond gc() 不会释放内存,如果内存最终不会通过普通 gc 释放..
    • 谢谢@Esailija 你有更多关于 v8 gc 的信息吗?你在哪里学习 v8
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多