我的Node.js应用程序似乎有内存泄漏。我快速构建它,我的JavaScript不是太强大,所以这可能很容易。
我已经对它做了一些堆转储,它是字符串object
?泄漏记忆,每5分钟约1MB。我扩展了String,它实际上是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;
});
}
}
仍在泄露记忆,但似乎只是在这些情况下:
答案 0 :(得分:5)
帮自己一个忙,并使用node-mysql,它是一个纯粹的javascript mysql客户端,速度很快。除此之外,您应该使用异步代码来阻止IO在您工作时被阻止。使用async库可以帮助您。它包含瀑布回调传递的代码。
至于你的内存泄漏,它可能不是socket.io,虽然我几个月没有使用它,我已经有成千上万的并发连接而且没有泄漏内存,我的代码不是最好的。
然而,有两件事。首先,你的代码很快就不可读了。我建议考虑正确格式化你的代码(我为每个缩进使用两个空格,但有些人使用四个)。其次,每半个小时打印一次连接数似乎有点傻,当你可以这样做时:setInterval(function() {
process.stdout.write('Current connections: ' + connections + ' \r');
}, 1000);
\r
将导致行被读回到行的开头并覆盖那里的字符,这将替换该行而不会创建大量的回滚。如果您选择在日志记录中添加调试详细信息,这将有助于调试。
您还可以使用process.memoryUsage()
快速检查内存使用情况(或节点认为您正在使用的数量)。
答案 1 :(得分:0)
当客户端断开连接时,这是否与连接的客户端阵列无法正常清除有关?数组值设置为NULL而不是从数组中删除。