javascript - headers - server on node js
Monitorear el consumo máximo de memoria en el proceso Node.js (2)
Estoy buscando una forma multiplataforma para monitorear de manera confiable el consumo máximo de memoria en el proceso Node.js, independientemente de si hay fugas o no.
Los procesos en mi caso son tanto aplicaciones reales como pruebas sintéticas.
Espero que funcione como
process.on(''exit'', () => {
console.log(''Max memory consumption: '' + ...);
});
Fue posible rastrear el consumo de memoria de alguna manera con el node --trace_gc ...
, pero esto resultó en una salida que es difícil de leer (y probablemente difícil de analizar mediante programación). Además, GC no se produjo cuando un script terminó demasiado rápido, incluso si el uso de RAM era considerable.
Por lo que he visto sobre el tema, usualmente se sugiere un memwatch
para eso, como:
require(''memwatch-next'').on(''stats'', stats => {
console.log(''Max memory consumption: '' + stats.max);
});
Pero en mi caso solo se activó cuando GC ya sucedió o no se activó en absoluto, por lo que fue inútil para determinar los picos de consumo de RAM.
Preferiría evitar las herramientas GUI como node-inspector
si es posible.
¿Se puede recuperar de forma confiable este consumo máximo de memoria como un número de la aplicación en sí o CLI solo, multiplataforma?
Podría usar el método Node.js process.memoryUsage()
para obtener la estadística de uso de memoria:
El método process.memoryUsage () devuelve un objeto que describe el uso de memoria del proceso Node.js medido en bytes.
Devuelve el objeto del siguiente formato:
{
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
}
Para obtener el consumo máximo de memoria en el proceso Node.js, se puede usar el método process.nextTick
. process.nextTick()
método process.nextTick()
agrega la devolución de llamada a la siguiente cola de tictac . Una vez que el turno actual del bucle de eventos se complete, se llamarán todas las devoluciones de llamada que se encuentran actualmente en la siguiente cola de tics.
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 trata de evaluar el proceso desde dentro de sí mismo, tendrá valores de uso de memoria distorsionados. (Si quieres más información sobre esto, solo comenta)
Esta es una pequeña herramienta ( multiplataforma ) que codifiqué para verificar el uso de la memoria de otro proceso, genera un proceso independiente y observa cada 100 ms para el uso de la memoria con el fin de encontrar el pico más alto, genera cada vez que se encuentra un nuevo pico y se detiene una vez que el niño ha terminado.
Utiliza pidusage
que es un proceso de pidusage
(cpu% y) uso de memoria de un PID
Permite la personalización del spawn (los argumentos se pasan junto con el spawn) [podría actualizarse para el uso de la línea de comandos]
También funcionará con cualquier nombre binario de nodo, ya que reutilizará el utilizado para iniciar esta herramienta.
''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
}
}
Producirá la siguiente salida:
╒══════════╕
│ child.js │ PEAK MEM. : 28737536
╘══════════╛
[the analysis ended]
Esta herramienta evita que se agregue una cantidad al código del proceso que realmente desea comparar, por lo que de esta manera no obtendrá diferentes valores de uso de memoria, ya que su código de acumulación / evaluación también agregará el uso de memoria a ese proceso.