PM2 - Incorrect memory usage reading & possible memory leak with Node.js application

别等时光非礼了梦想. 提交于 2021-02-05 06:21:09

问题


When my node js server is running via pm2, it has a higher memory usage reading than the actual memory heap in the application when inspected in DevTools. More so, the value under memory in pm2 slowly increases over time, possibly indicating some kind of memory leak. This slow increase in memory usage also cannot be observed in DevTools.

Any explanation and/or solutions to these two (seemingly) strange occurrences?

This is my DevTools

This is pm2 list

here is my javascript code

var SSE = require('sse');
var https = require('https');
var fs = require('fs');
var url = require('url');
var mysql = require('mysql');
var schedule = require('node-schedule');

var options = {
    key: fs.readFileSync('pathto/ssl.key'),
    cert: fs.readFileSync('pathto/ssl.crt'),
    ca: fs.readFileSync('pathto/ssl.ca-bundle')
};


var pool = mysql.createPool({
    connectionLimit: 100,
    host: "host",
    user: "user",
    password: "pass",
    database: "db"
});

async function connectandrun() {
    try {

        var server = https.createServer(options, function(req, res) {
            var queryData = url.parse(req.url, true).query;
            res.writeHead(200, {
                'Content-Type': 'text/event-stream',
                'Access-Control-Allow-Origin': '*',
                'Cache-Control': 'no-cache',
                'Connection': 'keep-alive',
                'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,OPTIONS',
                'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
            });

            if (queryData.connectionid) {
                var connecitonid = queryData.connectionid;
            } else {
                var connecitonid = "";
            }

            var myconection = "myconnecction" + connecitonid;
            var uuserjson = {};
            uuserjson[myconection] = {
                Data: {
                    Element: null
                }
            };

            schedule.scheduleJob('*/3 * * * * *', function() {
                var runninginstance = main(uuserjson, queryData, myconection, res).catch(console.error);
                runninginstance = null;
            });

            res.on("close", function() {
                res.end();
                uuserjson[myconection] = null;
                myconection = null;
                connecitonid = null;
            });
        });

        server.listen(3000, '0.0.0.0', function() {
            var sse = new SSE(server);
            sse.on('connection', function(client) {
                client.send('hi there!');
            });
        });

    } finally {}
}

connectandrun().catch(console.error);

async function main(uuserjson, queryData, myconection, res) {


    pool.getConnection(function(err, con) {
        if (err) {
            console.log(err);
        } else {
            con.query("MYSQL QUERY",
                function(err, result, fields) {
                    if (err) throw err;
                    if (result.length != 0) {
                        uuserjson[myconection] = {
                            Data: {
                                Element: result[0]
                            }
                        };

                        if (result[0]) {
                            res.write("retry: 30000\n\n" + "event: blanks\ndata: " + result[0] + "\n\n");
                        }
                    }

                    con.release();
                });
        }
    });

}

回答1:


After teaming up with OP on this, it has been confirmed there is some sort of memory leak in PM2.

Please see the below 'write-up' on our findings:


The Issue:

  • Slowly over time PM2 uses more and more RAM
    • This points to some sort of memory leak

Evidence & Rumors:

  • When running the application without PM2, just using node myserver.js, there is no evidence of RAM slowly increasing over time
    • RAM remains flat
    • The application that was used to test this theory is a small web app, in order to minimize the chance that the code contains a memory leak, and that the leak is in fact coming from PM2
  • There have been 'rumors' and evidence of memory leaks in PM2 for quite some time now - going back as far as 4 years (this answer was written in December 2019)
  • Someone describing why they stopped using PM2
    • See last comment
  • Thread where others are describing similar issues
    • That do not occur when PM2 is NOT used
  • Bug filed on PM2 GitHub with a confirmed memory leak
    • This bug was filed this year [2019] and at the time of this writing has comments as recent as October, where someone describes how this is still an issue

PM2 Alternatives You Should Consider:

  • Phusion Passenger seems like a strong candidate for replacing PM2
    • `Quick-start guide can be found here
    • Phusion Passenger looks like the closest comparison to PM2 and is where I would start
    • No, I do not have any affiliation with Phusion Passenger...
  • Forever
    • Does not seem like it is actively being maintained (in some of the issues filed on their GitHub people recommend using other apps)
  • Nodemon
    • Not really 'apples to apples' with PM2, but hey, variety is the spice of life
  • Naught
    • Does not appear to be actively maintained and is kind of 'small' in terms of stars
  • Native Node.js cluster

PM2 Workarounds/Band-Aids: (!not recommended to rely on these in Production!)

  • Set a Memory Threshold to auto-reload PM2 once X amount of RAM has been consumed
    • This 'feature' is native within PM2
  • Use a Cron Job to restart PM2 every X hours
    • Another example of a Cron Job


来源:https://stackoverflow.com/questions/59474575/pm2-incorrect-memory-usage-reading-possible-memory-leak-with-node-js-applica

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!