我正在使用 websockets 传输视频文件,这意味着它们是大文件。 服务器端(以及客户端)使用 nodejs 实现,在 javascript 中使用 binaryjs。
它运行良好,直到我开始拥有大量客户端,导致服务器崩溃(进程被 Linux 操作系统终止)。正如我所观察到的,它耗尽了内存,因为对于每个客户端来说,它都占用了很多内存,但问题是当客户端断开连接时,这个内存并没有被释放。我认为这应该在内部完成,我不应该担心内存,我错了吗?我可能做错了什么吗?
如我所见,“发送”函数正在保留内存以保存它必须发送的内容,但从不释放它。 (如果你评论那一行,就没有内存问题) 这是代码:
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");
});
});
当客户端收到所有视频文件时,关闭套接字,所以我知道它正在关闭,因为我正在捕获服务器上的“关闭”事件。这时候不应该释放内存吗?
最糟糕的是,因为我找不到错误,我认为这可能是由于 binaryjs 如何实现它,所以我也尝试在内存中使用“ws”和“websocket-node”得到相同的结果。
有人遇到过这个问题吗?有什么想法吗?
最佳答案
Shouldn't it at this moment free the memory
不,JavaScript 是一种垃圾收集语言,垃圾收集器会在运行时认为合适时定期运行。您无法控制也不知道它何时或是否会运行,因此会释放内存。
此外,您不能在网络服务器中使用任何同步 IO 调用,因为在您执行每个 IO 调用时,所有客户端处理都会阻塞。
我认为您的主要问题是您没有以相当小的 block 流式传输文件。您正在尝试将整个文件读入内存并将它们发送下来。
var buf = new Buffer(fs.fstatSync(fd).size, 'binary');
不要那样做。使用 ReadableStream 并以一系列小块的形式向下发送文件,并使用异步调用。这是让 Node 为您正确工作的方法。缺少流和异步调用是 Node 失败的必然路径。这是一个工作示例程序。
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);
});
我在 OSX 上用 Node v0.10.7 测试了这个,我可以用 curl localhost:9200 >/dev/null
重复请求文件看着lsof -p <pid of node>
我可以看到 /tmp/test
文件正确打开和关闭。
关于javascript - nodejs websocket 服务器中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16721995/