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

Est*_*ask 21 javascript profiling node.js

我正在寻找一种跨平台的方法来可靠地监视Node.js进程中的最大内存消耗,无论是否存在泄漏.

我的案例中的过程都是真实的应用程序和综合测试.

我希望它能起作用

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

有可能以某种方式跟踪内存消耗node --trace_gc ...,但这导致输出难以阅读(并且可能难以以编程方式分析).此外,当脚本结束太快时,即使RAM使用量很大,也不会发生GC.

从我在这个问题上看到的情况来看,通常memwatch建议如下:

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

但在我的情况下,它仅在GC已经发生或根本没有触发时触发,因此它对于确定RAM消耗峰值是无用的.

node-inspector如果可能的话,我宁愿避免使用GUI工具.

这个最大内存消耗是否可以从应用程序本身或单独的CLI(跨平台)中可靠地检索?

ale*_*mac 10

您可以使用Node.js process.memoryUsage()方法获取内存使用情况:

process.memoryUsage()方法返回一个对象,该对象描述以字节为单位测量的Node.js进程的内存使用情况.

它返回以下格式的对象:

{
  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
}
Run Code Online (Sandbox Code Playgroud)

要在Node.js进程中获得最大内存消耗,process.nextTick可以使用方法.process.nextTick()method将回调添加到下一个tick队列.一旦事件循环的当前转弯转到完成,将调用当前在下一个滴答队列中的所有回调.

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}`);
});
Run Code Online (Sandbox Code Playgroud)


EMX*_*EMX 5

如果您尝试从自身内部对流程进行基准测试,您将获得扭曲的内存使用值。(如果您想了解更多有关此的信息,请发表评论)


这是我编写的一个小(跨平台)工具,用于检查另一个进程的内存使用情况,它生成一个独立进程并每 100 毫秒监视一次内存使用情况以找到最高峰值,每次发现新峰值时输出并停止一次子进程结束了。

它使用pidusage哪个是PID的跨平台进程(cpu % 和)内存使用情况

允许自定义 spawn(参数与 spawn 一起传递)[可以更新为命令行使用]

它也适用于任何节点二进制名称,因为它将重用用于启动此工具的二进制名称。

'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
 }
}
Run Code Online (Sandbox Code Playgroud)

将产生以下输出:

 ???????????? 
 ? child.js ? PEAK MEM. : 28737536 
 ????????????
              [the analysis ended]
Run Code Online (Sandbox Code Playgroud)

此工具可防止您将膨胀添加到您实际要进行基准测试的进程的代码中,这样您就不会获得不同的内存使用值,因为您的膨胀/基准测试代码也会向该进程添加内存使用。