
Node は、サーバー側の Javascript のランタイムとして、JavaScript のアプリケーション シナリオを大幅に強化します。
しかし、Node.js ランタイム自体はブラックボックスであり、ランタイムの状態を認識することができず、オンライン上での問題を再現することは困難です。
したがって、パフォーマンスの監視は、Node.js アプリケーションの「通常の動作」の基礎となります。さまざまな実行時インジケーターをいつでも監視できるだけでなく、異常なシナリオの問題のトラブルシューティングにも役立ちます。
パフォーマンス監視は、パフォーマンス インジケータの収集と表示の 2 つの部分に分けることができます
。
パフォーマンス データのキャプチャと分析

上の図から、現在主流の 3 つの Node.js パフォーマンス監視ソリューションの長所と短所がわかります。以下に、これら 3 つのソリューションの構成を簡単に紹介します。
Prometheus
AliNode を形成するための問題のトラブルシューティングにのみ必要です。
Alinode は、公式の Nodejs と互換性のある拡張ランタイムであり、いくつかの追加機能を提供します:
は、パフォーマンス インジケーターを収集するために使用される常駐プロセスです。
、
監視、表示、スナップショット、分析までの閉ループを形成しますが、
Easy-Monitor
Node.js Addon
現在のプロセスの CPU 時間消費データはprocess.cpuUsage()戻り値の単位はマイクロ秒です。

現在のプロセスのメモリ割り当てデータはprocess.memoryUsage()を通じて取得できます。戻り値の単位はバイトです。

上の図からわかるように、 rssはコード セグメント ( Code Segment )、スタック メモリ ( Stack )、およびヒープ メモリ ( Heap ) が含まれています。
v8.getHeapStatistics()およびv8.getHeapSpaceStatistics()次の図は、v8 のヒープ メモリ構成の分布を示しています。

ヒープ メモリ空間はまずスペースに分割され、そのスペースは 1MB のアライメントに従ってページ化されます。
新しいスペース: 新しい世代のスペース。ライフ サイクルが比較的短いオブジェクト データを保存するために使用され、2 つのスペース (スペース タイプはsemi space ) に分割されます。 from space to space
古いスペース: New Spaceによってプロモートされたオブジェクトを格納するために使用される古い世代スペース
コード スペース: v8 JIT によってコンパイルされた実行可能コードを格納します。
マップ スペース: Object が指す隠しクラスのポインター オブジェクトを格納します。ランタイムに応じて、オブジェクト レイアウト構造は、オブジェクト メンバーに迅速にアクセスするために使用されます。
ラージ オブジェクト スペース: ページに割り当てられない 1MB を超えるオブジェクトを格納するために使用さ
ます
Mark-Sweep-Compactアルゴリズムを使用します。Scavenge
前提: New space 、 fromとto
トリガーのタイミング: New spaceがいっぱいになったとき。
手順:
from spaceで、幅優先の走査を実行し
、生き残った (到達可能な) オブジェクトが
Old spaceとto spaceto spaceが終了すると、 from spaceスペースが空になり、
from spaceからto spaceの交換が行われ、次のラウンドScavengeが開始されます。
頻繁なリサイクルやメモリ不足に適しています。大きなオブジェクトの場合、一般的なスペースフォータイム戦略には、

3 つのステップ: マーキング、クリア、整理
トリガー タイミング: Old spaceがいっぱいになったとき
ステップ:
マーキング (3 色マーキング方法)。
marking queue (明示的スタック) に入れ、これらのオブジェクトをグレーとしてマークします。marking queueからpopて黒にマークしmarking queueにpushスイープは
。コンパクト
Old spacev8 が最初にガベージ コレクションを実行するときは、プログラムを再実行する前にプログラムを停止し、ヒープ全体をスキャンし、メモリを再利用する必要があります。この動作は完全停止 ( Stop-The-World ) と呼ばれます
が、新しい世代のアクティブなオブジェクトは小さく、頻繁にリサイクルされますが、完全な停止はほとんど影響を与えません。マーキング、クリーニング、仕分けなどによる一時停止も発生します。さらに深刻になります。
この概念は、実際には React フレームワークのファイバー アーキテクチャに似ています。ブラウザーの空き時間中のみファイバー ツリーを通過して、対応するタスクを実行します。それ以外の場合、実行は遅延し、メイン スレッドのタスクへの影響は最小限に抑えられます。 、アプリケーションの遅延を回避し、アプリケーションのパフォーマンスを向上させます。
v8 には新世代と旧世代のスペースにデフォルト制限があるため、
New spaceデフォルト制限は 64 ビット システムの場合は 32M、Old spaceデフォルト制限は 64 ビット システムの場合は 1400M ですしたがって、 node新世代と旧世代のスペースの上限を調整するために 2 つのパラメーターが提供されます
--max-semi-space-size : New Spaceのスペース--max-old-space-size--max-old-space-size : Old Spaceの最大値を設定します spacenodeは、GC ログを表示する 3 つの方法もあります:
--trace_gc : ログの 1 行に、各 GC の時間、タイプ、ヒープ サイズの変更と原因が簡単に説明されます--trace_gc_verbose : 各 GC 後の各 V8 ヒープを表示します。スペースの詳細なステータス--trace_gc_nvp : GC タイプ、一時停止時間、メモリ変更などを含む、各 GC の詳細なキーと値のペア情報。GCログは比較的原始的であり、必要な情報を必要とします
。二次処理には、AliNode チームが開発した v8-gc を使用できます。Heapsnapshot
実行中のプログラムのヒープ メモリのスナップショットを取得し、メモリ消費を分析し、
Heapsnapshot ファイルのできます.heapsnapshot次の方法で生成されます:
heapdump を使用する

v8 のヒープ プロファイルの使用

Nodejs の組み込み v8 モジュールによって提供される
APIv8.getHeapSnapshot()

v8.writeHeapSnapshot(fileName)

v8-profiler-next の使用

、Chrome devtools ツールバーのメモリにアップロード.heapsnapshot 、結果は次のように表示されます。

デフォルトのビューはSummaryビューです。ここでは、右端の 2 つの列に注意する必要があります: Shallow Size Retained Size
Shallow Size v8 ヒープ メモリに割り当てられたオブジェクト自体のサイズを示しますRetained Sizeオブジェクトのすべての参照オブジェクトのShallow SizeRetained Size大きいことが判明した場合、オブジェクト内でメモリ リークが発生している可能性があるため、
Comparisonビューを使用して比較
2 つの異なる期間のヒープ スナップショットを分析する場合、 Delta列を使用して、メモリ変更が最も大きいオブジェクトを除外できます。

、プログラムを実行しているCPU のスナップショット サンプリングを実行します。これは、CPU 時間と割合を分析するために使用できます。
.cpuprofileファイルを生成するには、いくつかの方法があります。
これは 5 分間の CPU プロファイル サンプル コレクションです
。
Javascript Profiler生成された.cpuprofileファイルは、

デフォルトのビューはHeavyビューです。ここではSelf TimeとTotal Time
Total Time実行時間を表しますSelf Time他の呼び出しを除く)。アプリケーションが予期せずクラッシュして終了した場合は、
Self Time Total Timeシューティングを行うこともできます
システムはそれを自動的に記録します。プロセスはその時点でメモリ割り当て情報、プログラム カウンター、スタック ポインター、およびその他の重要な情報をクラッシュし
、.core ファイルを.core 3 つの方法:
ulimit -c unlimitedカーネル制限を開きます。node --abort-on-uncaught-exceptionの起動時にこのパラメータを追加すると、アプリケーションでキャッチされない例外が発生したときにコア ファイルを生成できます。gcore <pid>.coreファイルを取得した後、解析と解析
診断は、mdb、gdb、lldb などのツールを通じて行うことができます。 プロセス クラッシュの実際の原因
llnode `which node` -c /path/to/core/dump
監視すると、ヒープ メモリが増加し続けていることがわかります。そのため、トラブルシューティング

heapsnapshot分析すると、比較的大きなメモリを常に保持しているnewThingオブジェクトが存在することがわかります

newThing theThing unused
クロージャによって引き起こされるreplaceThingのケースには、
などの状況が含まれます
。したがって、上記の状況では、メモリ内のオブジェクトが自動的にリサイクルされるかどうかを慎重に検討する必要があります。自動的にリサイクルされない場合は、オブジェクトを手動でnullに設定する、タイマーを削除する、イベント リスナーをバインド解除するなど、手動でリサイクルする必要があります。
、Node.js パフォーマンス監視システム全体について詳しく説明しました。
まず、パフォーマンス監視によって解決される問題、そのコンポーネント、および主流のソリューションの長所と短所の比較を紹介します。
次に、パフォーマンス インジケーターとスナップショット ツールの 2 つの主要な部分を詳細に紹介します。
最後に、観察、分析、トラブルシューティングから単純なメモリ リークのケースを再現し、一般的なメモリ リークの状況と解決策をまとめます。
この記事が、皆さんが Node.js パフォーマンス監視システム全体を理解するのに役立つことを願っています。