内存泄漏与socket.io + node.js

我的节点应用程序似乎有内存泄漏。 我很快就构build了它,而且我的JavaScript不是太强大,所以这可能很简单。

我已经做了一些堆转储,它是string'对象'? 内存泄漏,每5分钟约1MB。 我扩展string,它实际上是String.Array?

堆栈: http : //i.imgur.com/ZaBp0.png

#!/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; }); } } 

仍然泄漏的记忆,但似乎只有在这些条件:

  • 从创业开始,没有客户 – >好
  • 第一个客户端连接 – >好
  • 第二个客户端(即使第一个客户端断开连接并重新连接) – >内存泄漏
  • 停止所有连接 – >好
  • 1个新连接(连接= 1) – >内存泄漏

帮你一个忙,使用node-mysql ,它是一个纯粹的JavaScript MySQL客户端,速度很快。 除此之外,您应该使用asynchronous代码来阻止IO在工作时被阻塞。 使用asynchronous库将帮助你在这里。 它有瀑布callback传递代码等等。

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

两件事,但是。 首先你的代码是不可读的。 我build议寻找正确格式化你的代码(每个缩进使用两个空格,但有些人使用四个)。 其次,每半小时打印一次连接数似乎有点傻,你可以这样做:

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

\r将导致该行被读回到行首,并覆盖那里的字符,这将取代行,而不是创build大量的回滚。 如果您select在日志logging中放置debugging详细信息,这将有助于debugging。

您也可以使用process.memoryUsage()来快速检查内存使用情况(或多less节点认为您正在使用)。

当客户端断开连接时,这可能与连接的客户端arrays没有正确清理有关吗? 数组值被设置为NULL,而不是从数组中删除。