Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Memory usage keeps going up #4276

@david-innover

Description

@david-innover

Hi,

We are writing a script that reads a large set of JPG files on our server (infinite, since we have another process that keeps writing JPG files to the same directory) and send them to users' browsers as an MJPEG stream at fixed time interval (variable "frameDelay" in code below). This is similar to what an IP camera would do.

We found out the memory usage of this script keeps going up and always ends up being killed by the system (Ubuntu);

It's also possible that they were caused by our mistakes in the code (although we have inspected this seemingly simple script many many times). Therefore I'm posting the code below. Any comments / suggestions are greatly appreciated!

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);

To facilitate the troubleshooting process, below is a stand-alone (no 3rd-party lib) test case.

It has exactly the same memory issue (memory usage keeps going up and finally got killed by the OS).

We believe the problem is in the setInterval () loop - maybe those images didn't get deleted from memory after being sent or something (maybe still stored in variable "res"?).

Any feedback / suggestions are greatly appreciated!

    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);                                                               

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions