Monitor maximum memory consumption in Node.js process
If you try to benchmark the process from within itself, you will have distorted memory usage values. (if you want more information about this, just comment)
This is a little (crossplatform) tool I coded for checking the memory usage of another process, it spawns an independent process and watches every 100ms for memory usage in order to find the highest peak, outputs everytime a new peak is found and stops once child has ended.
It uses pidusage
which is a crossplatform process ( cpu % and ) memory usage of a PID
Allows customization of the spawn (arguments to be passed along with the spawn) [could be updated for command line usage]
It will also work with any node binary name, since it will reuse the one used to start this tool.
'use strict'
const UI = {}; var ñ = " "
const pusage = require('pidusage');
//:Setup the 'cmd' array to be the file and arguments to be used
const ANALYSIS = {cmd:['child.js']}
ANALYSIS.child = require('child_process').spawn(
process.argv[0], // reuse to work with the same binary name used to run this (node|nodejs|...)
ANALYSIS.cmd, // array with filePath & arguments to spawn for this analisis
{ //So the child_process doesn't behave like a child
detached:true,
stdio:['ignore'],
env:null
}
);
//:The Analysis
DoAnalysis(ANALYSIS.child.pid);
ANALYSIS.child.unref()
var memPeak = 0;
function PIDStat(){
pusage.stat(ANALYSIS.pid, function(err, stat) {
if(err){ CheckError(err) }else{
if(stat.memory > memPeak){memPeak=stat.memory;PrintStat()}
setTimeout(PIDStat,100); pusage.unmonitor(process.pid)
}
})
}
//:UI (just for display)
function DoAnalysis(PID){
var s = '═'.repeat(ANALYSIS.cmd[0].toString().length)
ANALYSIS.pid = PID;
UI.top = '╒═'+s+'═╕'
UI.mid = '│ '+ANALYSIS.cmd[0]+' │'
UI.bot = '╘═'+s+'═╛'
console.log(UI.x);
PIDStat()
}
function PrintStat(){
console.clear()
console.log('\n',UI.top,'\n',UI.mid,'PEAK MEM. :',memPeak,'\n',UI.bot)
}
function CheckError(e){
switch(e.code){
case "ENOENT": console.log(" [the analysis ended]\n"); break;
default: console.log("[/!\\ error]\n",e); break
}
}
Will produce the following output :
╒══════════╕
│ child.js │ PEAK MEM. : 28737536
╘══════════╛
[the analysis ended]
This tool prevents you from adding bloat to the code of the process you actually want to benchmark, so this way you wont get different memory usage values, since your bloat/benchmarking code will also add memory usage to that process.
You could use Node.js process.memoryUsage()
method to get memory usage stat:
The process.memoryUsage() method returns an object describing the memory usage of the Node.js process measured in bytes.
It returns the object of the following format:
{
rss: 4935680, // Resident Set Size
heapTotal: 1826816, // Total Size of the Heap
heapUsed: 650472, // Heap actually Used
external: 49879 // memory usage of C++ objects bound to JavaScript objects managed by V8
}
To get the maximum memory consumption in Node.js process, process.nextTick
method could be used. process.nextTick()
method adds the callback to the next tick queue. Once the current turn of the event loop turn runs to completion, all callbacks currently in the next tick queue will be called.
let _maxMemoryConsumption = 0;
let _dtOfMaxMemoryConsumption;
process.nextTick(() => {
let memUsage = process.memoryUsage();
if (memUsage.rss > _maxMemoryConsumption) {
_maxMemoryConsumption = memUsage.rss;
_dtOfMaxMemoryConsumption = new Date();
}
});
process.on('exit', () => {
console.log(`Max memory consumption: ${_maxMemoryConsumption} at ${_dtOfMaxMemoryConsumption}`);
});