问题
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 usingnode 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
- That do not occur when
- 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
- Not really 'apples to apples' with
- 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
- This 'feature' is native within
- 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