内存泄漏在nodejs websocket服务器中

我使用websockets来传输video文件,这意味着他们是大文件。 服务器端(也是客户端)使用nodejs实现,在javascript中使用binaryjs。

它运行良好,直到我开始有大量的客户端,是什么使服务器崩溃(Linux操作系统杀死进程)。 正如我所观察到的,它耗尽了内存,因为对于每个客户端来说,它都占用了大量内存,但是当客户端断开连接时,这个内存不会被释放。 我认为这应该在内部完成,我不应该担心记忆,我错了吗? 我可能做错了什么?

正如我所看到的那样,“发送”function是保留内存来保存它发送的内容,但是永远不会释放它。 (如果您评论该行,则不存在内存问题)以下是代码:

var fs = require('fs'); var BinaryServer = require('binaryjs').BinaryServer; var bs = BinaryServer({port: 8080}); var nchunks=116; bs.on('connection', function(client){ for(var i=1; i<=nchunks; i++) { var name="/var/www/1.m4s"; var fd=fs.openSync(name.replace("1.m4s", i+".m4s"), 'r'); var buf = new Buffer(fs.fstatSync(fd).size, 'binary'); fs.readSync(fd, buf, 0, buf.length, null) client.send(buf); fs.closeSync(fd); if(i==nchunks){ client.send("end"); } } client.on('close', function(c){ console.log("closing"); }); 

});

当客户端收到所有的video文件,closures套接字,所以我知道它正在closures,因为我在服务器上捕获“closures”事件。 不应该在这个时候释放内存吗?

最糟糕的是,因为我找不到错误,所以我认为这可能是由于binaryjs如何实现的,所以我试着在内存中使用“ws”和“websocket-node”来获得相同的结果。

有没有人遇到过这个问题? 任何想法?

不应该在这个时候释放内存

不,JavaScript是一种垃圾收集语言,垃圾收集器在运行时认为合适的时候会周期性地运行。 你无法控制,也不知道何时或是否会运行,从而释放记忆。

另外,不能在networking服务器中使用任何同步IO调用,因为在执行每个IO调用时,您的所有客户端处理都将阻塞。

我认为你的主要问题是你没有以合理的小块stream式传输文件。 您正尝试将整个文件读入内存并将其发送出去。

 var buf = new Buffer(fs.fstatSync(fd).size, 'binary'); 

不要这样做。 使用ReadableStream并以一系列小块发送文件,并使用asynchronous调用。 这是如何让节点为您正确工作。 缺lessstream媒体和缺乏asynchronous调用肯定会导致节点故障。 这是一个工作示例程序。

 var fs = require("fs"); var http = require("http"); var server = http.createServer(); server.listen(9200) server.on('request', function (req, res) { fs.createReadStream('/tmp/test1').pipe(res); }); 

我使用节点v0.10.7在OSX上testing了这一点,我可以用curl localhost:9200 >/dev/null重复请求这个文件,并且观察lsof -p <pid of node>我可以看到/tmp/test文件被打开并closures正常。