Surveiller la consommation maximale de mémoire dans le noeud.processus js
je suis à la recherche d'un moyen multiplateformes pour surveiller de façon fiable la consommation maximale de mémoire dans le noeud.processus js, qu'il y ait ou non des fuites.
les processus dans mon cas sont à la fois des applications réelles et des tests synthétiques.
je m'attends à ce qu'il fonctionne comme
process.on('exit', () => {
console.log('Max memory consumption: ' + ...);
});
il était possible de retracer la consommation de mémoire d'une façon ou d'une autre avec node --trace_gc ...
, mais cela a abouti à une sortie qui est difficile à lire (et probablement difficile à analyser programmatiquement). Également, GC ne se produisait pas quand un script finissait trop vite, même si L'utilisation de la RAM était importante.
De ce que j'ai vu sur le sujet, généralement memwatch
est suggéré pour que, comme:
require('memwatch-next').on('stats', stats => {
console.log('Max memory consumption: ' + stats.max);
});
mais dans mon cas, il n'a été déclenché que lorsque GC s'est déjà produit ou ne s'est pas déclenché du tout, donc il était inutile pour déterminer les pics de consommation de RAM.
je préfère éviter d'outils graphiques comme node-inspector
si possible.
cette consommation maximale de mémoire peut-elle être fiable? extrait en tant que numéro de l'application elle-même ou CLI seul, cross-plate-forme?
2 réponses
vous pourriez utiliser le noeud.js process.memoryUsage()
méthode pour obtenir l'utilisation de la mémoire stat:
Le processus.la méthode memoryUsage () renvoie un objet décrivant l'utilisation de la mémoire du noeud.processus js mesuré en octets.
Il renvoie l'objet du format suivant:
{
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
}
pour obtenir la consommation de mémoire maximale dans le noeud.processus js,process.nextTick
méthode pourrait être utilisée. process.nextTick()
la méthode ajoute le rappel au suivant cochez la file d'attente. Une fois l' tour actuel de la boucle d'événement le tour s'exécute jusqu'à son achèvement, toutes les callbacks actuellement dans la prochaine file d'attente seront appelées.
let _maxMemoryConsumption;
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}`);
});
si vous essayez de comparer le processus de l'intérieur de lui-même, vous aurez déformé les valeurs d'utilisation de la mémoire. (si vous voulez plus d'informations à ce sujet, juste un commentaire)
C'est un peu (compatible) outil que j'ai codé pour vérifier l'utilisation de la mémoire d'un autre processus, il produit un processus indépendant et regarde tous les 100ms pour l'utilisation de la mémoire afin de trouver le pic le plus élevé, les sorties chaque fois qu'un nouveau pic est trouvé et s'arrête une fois que l'enfant a terminer.
pidusage
qui est un processus crossplatform (cpu % et)mémoire utilisation d'un PID
Permet la personnalisation du spawn (les arguments passés avec le spawn) [pourrait être mis à jour pour l'utilisation de lignes de commande]
il fonctionnera aussi avec n'importe quel nom binaire de noeud, puisqu'il réutilisera celui utilisé pour démarrer cet outil.
'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
}
}
produira la sortie suivante :
╒══════════╕
│ child.js │ PEAK MEM. : 28737536
╘══════════╛
[the analysis ended]
cet outil vous empêche d'ajouter du bloat au code du processus que vous voulez réellement comparer, de cette façon vous n'obtiendrez pas différentes valeurs d'utilisation de la mémoire, puisque votre code de bloat/benchmarking ajoutera également l'utilisation de la mémoire à ce processus.