内存泄漏与socket.io + node.js [英] Memory Leak with socket.io + node.js

查看:140
本文介绍了内存泄漏与socket.io + node.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Node.js应用程序似乎有内存泄漏。我很快就构建了它,而且我的JavaScript也不是很强大,所以这可能很容易。

I appear to have a memory leak with my Node.js application. I built it quickly, and my JavaScript isn't too strong, so this might be easy.

我已经完成了一些堆转储,它就是String 物体?泄漏记忆,每5分钟约1MB。我扩展了String,它实际上是String.Array?

I've done some heap dumps on it, and it's the String object? leaking memory, at the rate of about 1MB every 5 minutes. I expanded String, and it's actually String.Array?

堆栈:

#!/usr/local/bin/node

var port = 8081;

var io = require('socket.io').listen(port),
sys = require('sys'),
daemon = require('daemon'),
mysql = require('mysql-libmysqlclient');

var updateq = "SELECT 1=1";
var countq = "SELECT 2=2";

io.set('log level', 2);


process.on('uncaughtException', function(err) {
  console.log(err);
});

var connections = 0;

var conn = mysql.createConnectionSync();
dbconnect();

io.sockets.on('connection', function(client){ 
  connections++;
  client.on('disconnect', function(){ connections--;  }) 
});

process.on('exit', function () {
    console.log('Exiting');
    dbdisconnect();
});

function dbdisconnect() {
     conn.closeSync();
}

function dbconnect() {
    conn.connectSync('leet.hacker.org','user','password');
}


function update() {
    if (connections == 0)
        return;
    conn.query(updateq, function (err, res) {
      if (err) {
        dbdisconnect();
        dbconnect();
        return;
      }
      res.fetchAll(function (err, rows) {
        if (err) {
          throw err;
        }
        io.sockets.json.send(rows);
      });
    });
}

function totals() {
    if (connections == 0)
        return;
        conn.query(countq, function (err, res) {
          if (err) {
        // Chances are that the server has just disconnected, lets try reconnecting
        dbdisconnect();
        dbconnect();
            throw err;
          }
          res.fetchAll(function (err, rows) {
            if (err) {
              throw err;
            }
        io.sockets.json.send(rows);
          });
        });

}

setInterval(update, 250);
setInterval(totals,1000);

setInterval(function() {
console.log("Number of connections: " + connections);
},1800000);



  daemon.daemonize('/var/log/epiclog.log', '/var/run/mything.pid', function (err, pid) {
    // We are now in the daemon process
    if (err) return sys.puts('Error starting daemon: ' + err);

    sys.puts('Daemon started successfully with pid: ' + pid);
  });

当前版本

function totals() {

        if (connections > 0)
        {
                var q = "SELECT query FROM table";

            db.query(q, function (err, results, fields) {
            if (err) {
                    console.error(err);
                    return false;
            }

            for (var row in results)
            {
                    io.sockets.send("{ ID: '" + results[row].ID + "', event: '" + results[row].event + "', free: '" + results[row].free + "', total: '" + results[row].total + "', state: '" + results[row]$
                    row = null;
            }


            results = null;
            fields = null;
            err = null;
            q = null;
            });
    }
}

仍在泄漏内存,但似乎只是在这些条件下:

Still leaking memory, but it seems only on these conditions:


  • 从启动,没有客户端 - >好

  • 第一个客户端连接 - >精细

  • 第二个客户端(即使第一个客户端断开连接并重新启动连接) - >泄漏内存

  • 停止所有连接 - >精细

  • 1个新连接(连接= 1) - >内存泄漏

  • From startup, with no clients -> Fine
  • 1st client connection -> Fine
  • 2nd client (even with the 1st client disconnecting and reconnecting) -> Leaking memory
  • Stop all connections -> Fine
  • 1 new connection (connections = 1) -> Leaking memory

推荐答案

帮自己一个忙,并使用 node-mysql ,它是一个纯粹的javascript mysql客户端,速度很快。除此之外,您应该使用异步代码来阻止IO在您工作时被阻止。使用异步库将为您提供帮助。它有瀑布回调传递的代码。

Do yourself a favour and use node-mysql, it's a pure javascript mysql client and it's fast. Other than that, you should be using asynchronous code to stop IO being blocked whilst you're working. Using the async library will help you here. It has code for waterfall callback passing among other things.

至于你的内存泄漏,它可能不是socket.io,虽然我还没有在它中使用它几个月,我有成千上万的并发连接而没有泄露内存,我的代码也不是最好的。

As for your memory leaking, it probably isn't socket.io, although I haven't used it in a few months, I have had many thousands of concurrent connections and not leaked memory, and my code wasn't the best either.

然而,有两件事情。首先,你的代码很快就不可读了。我建议考虑正确格式化你的代码(我为每个缩进使用两个空格,但有些人使用四个)。其次,每半小时打印连接数似乎有点傻,当你可以这样做时:

Two things, however. Firstly your code is faily unreadable. I suggest looking into properly formatting your code (I use two spaces for every indentation but some people use four). Secondly, printing the number of connections every half an hour seems a little silly, when you could do something like:

setInterval(function() {
  process.stdout.write('Current connections: ' + connections + '     \r');
}, 1000);

\ r 将导致该行要回读到行的开头并覆盖那里的字符,这将替换该行而不会创建大量的回滚。如果您选择在日志记录中添加调试详细信息,这将有助于调试。

The \r will cause the line to be read back to the start of the line and overwrite the characters there, which will replace the line and not create a huge amount of scrollback. This will help with debugging if you choose to put debugging details in your logging.

您还可以使用 process.memoryUsage()用于快速检查内存使用情况(或节点认为您正在使用的节点数)。

You can also use process.memoryUsage() for quickly checking the memory usage (or how much node thinks you're using).

这篇关于内存泄漏与socket.io + node.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆