簡體   English   中英

監視Node.js進程中的最大內存消耗

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

我正在尋找一種跨平台的方法來可靠地監視Node.js進程中的最大內存消耗,無論是否存在泄漏。

我的案例中的過程都是真實的應用程序和綜合測試。

我希望它能起作用

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

有可能通過node --trace_gc ...以某種方式跟蹤內存消耗,但這導致輸出難以閱讀(並且可能難以以編程方式分析)。 此外,當腳本結束太快時,即使RAM使用量很大,也不會發生GC。

從我在這個主題上看到的,通常建議使用memwatch ,如:

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

但在我的情況下,它僅在GC已經發生或根本沒有觸發時觸發,因此它對於確定RAM消耗峰值是無用的。

如果可能的話,我寧願避免像node-inspector器這樣的GUI工具。

這個最大內存消耗是否可以從應用程序本身或單獨的CLI(跨平台)中可靠地檢索?

您可以使用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
}

要在Node.js進程中獲得最大內存消耗,可以使用process.nextTick方法。 process.nextTick()方法將回調添加到下一個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}`);
});

如果您嘗試從內部對進程進行基准測試,則會使內存使用值失真。 (如果您想了解更多相關信息,請發表評論)


這是一個小的( 跨平台 )工具,我編碼用於檢查另一個進程的內存使用情況,它產生一個獨立的進程並監視每100ms的內存使用情況,以便找到最高峰值,每次發現新峰值時輸出,並在一旦孩子停止結束了。

它使用pidusage ,它是PID的pidusage平台進程(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
 }
}

將產生以下輸出:

 ╒══════════╕ 
 │ child.js │ PEAK MEM. : 28737536 
 ╘══════════╛
              [the analysis ended]

此工具可以防止您將bloat添加到您實際想要進行基准測試的進程的代碼中,因此這樣您就不會獲得不同的內存使用值,因為您的膨脹/基准測試代碼也會為該進程添加內存使用量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM