简体   繁体   English

监视Node.js进程中的最大内存消耗

[英]Monitor maximum memory consumption in Node.js process

I'm looking for a cross-platform way to reliably monitor maximum memory consumption in Node.js process, regardless of whether there are leaks or not. 我正在寻找一种跨平台的方法来可靠地监视Node.js进程中的最大内存消耗,无论是否存在泄漏。

The processes in my case are both real applications and synthetic tests. 我的案例中的过程都是真实的应用程序和综合测试。

I would expect it to work like 我希望它能起作用

process.on('exit', () => {
  console.log('Max memory consumption: ' + ...);
});

It was possible to trace memory consumption somehow with node --trace_gc ... , but this resulted in output that is hard to read (and probably hard to analyze programmatically). 有可能通过node --trace_gc ...以某种方式跟踪内存消耗,但这导致输出难以阅读(并且可能难以以编程方式分析)。 Also, GC didn't occur when a script ended too fast, even if RAM usage was substantial. 此外,当脚本结束太快时,即使RAM使用量很大,也不会发生GC。

From what I have seen on the subject, usually memwatch is suggested for that, like: 从我在这个主题上看到的,通常建议使用memwatch ,如:

require('memwatch-next').on('stats', stats => {
  console.log('Max memory consumption: ' + stats.max);
});

But in my case it triggered only when GC already happened or didn't trigger at all, so it was useless for determining RAM consumption peaks. 但在我的情况下,它仅在GC已经发生或根本没有触发时触发,因此它对于确定RAM消耗峰值是无用的。

I would prefer to avoid GUI tools like node-inspector if possible. 如果可能的话,我宁愿避免像node-inspector器这样的GUI工具。

Can this maximum memory consumption be reliably retrieved as a number from the application itself or CLI alone, cross-platform? 这个最大内存消耗是否可以从应用程序本身或单独的CLI(跨平台)中可靠地检索?

You could use Node.js process.memoryUsage() method to get memory usage stat: 您可以使用Node.js process.memoryUsage()方法获取内存使用情况:

The process.memoryUsage() method returns an object describing the memory usage of the Node.js process measured in bytes. process.memoryUsage()方法返回一个对象,该对象描述以字节为单位测量的Node.js进程的内存使用情况。

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. 要在Node.js进程中获得最大内存消耗,可以使用process.nextTick方法。 process.nextTick() method adds the callback to the next tick queue . process.nextTick()方法将回调添加到下一个tick队列 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}`);
});

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. 这是一个小的( 跨平台 )工具,我编码用于检查另一个进程的内存使用情况,它产生一个独立的进程并监视每100ms的内存使用情况,以便找到最高峰值,每次发现新峰值时输出,并在一旦孩子停止结束了。

It uses pidusage which is a crossplatform process ( cpu % and ) memory usage of a PID 它使用pidusage ,它是PID的pidusage平台进程(cpu%和) 内存使用情况

Allows customization of the spawn (arguments to be passed along with the spawn) [could be updated for command line usage] 允许自定义spawn(与spawn一起传递的参数) [可以更新命令行用法]

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. 此工具可以防止您将bloat添加到您实际想要进行基准测试的进程的代码中,因此这样您就不会获得不同的内存使用值,因为您的膨胀/基准测试代码也会为该进程添加内存使用量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM