gpt4 book ai didi

Node.js:内存使用量不断上升

转载 作者:搜寻专家 更新时间:2023-10-31 23:06:24 27 4
gpt4 key购买 nike

我们正在编写一个脚本来读取我们服务器上的大量 JPG 文件(无限,因为我们有另一个进程不断将 JPG 文件写入同一目录)并将它们作为 MJPEG 流以固定的速度发送到用户的浏览器时间间隔(下面代码中的变量“frameDelay”)。这类似于 IP 摄像机的功能。

我们发现这个脚本的内存占用一直在上升,最后总是被系统(Ubuntu)杀死;

我们已经多次检查这个看似简单的脚本。因此,我在下面发布了代码。非常感谢任何意见/建议!

app.get('/stream', function (req, res) {
res.writeHead(200, {
'Content-Type':'multipart/x-mixed-replace;boundary="' + boundary + '"',
'Transfer-Encoding':'none',
'Connection':'keep-alive',
'Expires':'Fri, 01 Jan 1990 00:00:00 GMT',
'Cache-Control':'no-cache, no-store, max-age=0, must-revalidate',
'Pragma':'no-cache'
});
res.write(CRLF + "--" + boundary + CRLF);

setInterval(function () {
if(fileList.length<=1){
fileList = fs.readdirSync(location).sort();
}else{
var fname = fileList.shift();
if(fs.existsSync(location+fname)){
var data = fs.readFileSync(location+fname);
res.write('Content-Type:image/jpeg' + CRLF + 'Content-Length: ' + data.length + CRLF + CRLF);
res.write(data);
res.write(CRLF + '--' + boundary + CRLF);
fs.unlinkSync(location+fname);
}else{
console.log("File doesn't find")
}
}
console.log("new response:" + fname);
}, frameDelay);
});

app.listen(port);
console.log("Server running at port " + port);

为了便于故障排除过程,下面是一个独立(无第 3 方库)测试用例。

它有完全相同的内存问题(内存使用量不断上升,最后被操作系统杀死)。

我们认为问题出在 setInterval () 循环中 - 也许这些图像在发送后没有从内存中删除或其他原因(可能仍存储在变量“res”中?)。

非常感谢任何反馈/建议!

var http                = require('http');
var fs = require('fs');

var framedelay = 40;
var port = 3200;
var boundary = 'myboundary';
var CR = '\r';
var LF = '\n';
var CRLF = CR + LF;

function writeHttpHeader(res)
{
res.writeHead(200,
{
'Content-Type': 'multipart/x-mixed-replace;boundary="' + boundary + '"',
'Transfer-Encoding': 'none',
'Connection': 'keep-alive',
'Expires': 'Fri, 01 Jan 1990 00:00:00 GMT',
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
'Pragma': 'no-cache',
});

res.write(CRLF + '--' + boundary + CRLF);
}

function writeJpegFrame(res, filename)
{
fs.readFile('./videos-8081/frames/' + filename, function(err, data)
{
if (err)
{
console.log(err);
}
else
{
res.write('Content-Type:image/jpeg' + CRLF);
res.write('Content-Length:' + data.length + CRLF + CRLF);
res.write(data);
res.write(CRLF + '--' + boundary + CRLF);
console.log('Sent ' + filename);
}
});
}
http.createServer(function(req, res)
{
writeHttpHeader(res)    
fs.readdir('./videos-8081/frames', function(err, files)
{
var i = -1;
var sorted_files = files.sort();    
setInterval(function()
{
if (++i >= sorted_files.length)
{
i = 0;
}    
writeJpegFrame(res, sorted_files[i]);
}, framedelay);
});
}).listen(port);
console.log('Server running at port ' + port);

最佳答案

当然会泄漏内存。你做

 setInterval(...)

在每个请求上,但您永远不会清理这些间隔。这意味着在(例如)20 个请求之后,您有 20 个间隔在后台运行,它们将永远运行,即使客户端/连接早已失效。解决方案之一如下:

var my_interval = setInterval(function() {
try {
// all your code goes here
} catch(e) {
// res.write should throw an exception once the connection is dead
// do the cleaning now
clearInterval( my_interval );
}
}, frameDelay);

req.on( "close", function() {
// just in case
clearInterval( my_interval );
});

这确保一旦连接关闭,my_interval(以及所有相应的数据)将被清除。

附言我建议使用 setTimeout 而不是 setInterval,因为加载文件可能比 frameDelay 花费更多的时间,这会导致问题。

附注 2。使用 fs 函数的异步版本。 Node.JS 的全部力量在于非阻塞操作,而您在这里失去了主要优势(性能)。

关于Node.js:内存使用量不断上升,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13348424/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com