V8 CPU とメモリのプロファイリング
IntelliJ IDEA を使用すると、 V8 のサンプルベースのプロファイラー(英語)を使用して Node.js アプリケーションの CPU プロファイルとヒープスナップショットをキャプチャーして分析できます。
Google Chrome DevTools でキャプチャーされたスナップショットを開いて、クライアント側のコード用に探索することもできます。
始める前に
Node.js をダウンロードしてインストールします。
設定で JavaScript and TypeScript プラグインが有効になっていることを確認します。 Ctrl+Alt+S を押して設定を開き、 を選択します。 インストール済み タブをクリックします。 検索フィールドに JavaScript と TypeScript と入力します。 プラグインに関する詳細は、 プラグインの管理を参照してください。
JetBrains Marketplace からプラグインをインストールする説明に従って、 設定 | プラグイン ページの Marketplace タブで Node.js プラグインをインストールして有効にします。 このプラグインは IntelliJ IDEA Ultimate でのみ利用可能です。
CPU プロファイリング
CPU プロファイリングを使用すると、コードのどの部分が最も CPU 時間を消費しているか、および V8 JavaScript エンジンによってコードがどのように実行および最適化されているかをよりよく理解できます。
IntelliJ IDEA の Node.js CPU プロファイリングは、V8 組み込み CPU プロファイラーに基づいています。これは、ガベージコレクションサイクル、コンパイルと再コンパイル、コードの最適化など、コードの実行と JavaScript エンジン自体の動作に関する情報を提供します。
プロファイラは、ティックと呼ばれる一定の間隔でスナップショットを撮ります。 測定は、コードの作業だけでなく、コンパイル、システムライブラリの呼び出し、最適化、ガベージコレクションなど、エンジン自体によって実行されるアクティビティについても行われます。
CPU プロファイリングを有効にする
アプリケーションの起動時に V8 CPU プロファイリングを呼び出すには、 Node.js 実行構成で追加設定を指定する必要があります。
に移動します。 または、ツールバーの 実行 ウィジェットから 実行構成の編集 を選択します。

開いた 実行構成の編集 ダイアログで、ツールバーの 追加 ボタン (
) をクリックし、リストから Node.js を選択します。
リストから Node.js 実行構成を選択して CPU プロファイリングを有効にするか、 Node.js の実行とデバッグ の説明に従って新しい設定を作成します。
V8 プロファイリング タブに切り替えて、 CPU プロファイリング情報を記録する チェックボックスを選択します。 ログフォルダー フィールドに、記録されたログを保管するフォルダーへのパスを指定します。ログ ファイルは
isolate-<session number>という命名で保存されます。
CPU プロファイリング情報を収集する
メインツールバーのリストから実行構成を選択して
をクリックするか、メインメニューから を選択します。
プロファイルする必要があるシナリオが実行されたら、ツールバーの
をクリックしてプロセスを停止します。
CPU プロファイリングログの分析
アプリケーションを停止すると、IntelliJ IDEA は自動的に V8 プロファイリング ツールウィンドウを開き、そこに収集されたプロファイリングデータを表示します。 ウィンドウがすでに開いていて別のセッションの収集データを表示している場合は、IntelliJ IDEA は新しいタブを開きます。 自動的に開かれたタブには、アプリケーションの実行を制御し、プロファイリングデータを収集する実行構成に基づいて名前が付けられます。
以前に保存したプロファイリングデータを開いて分析するには、 に移動して(または Ctrl+Shift+A を押して)、 V8 と入力し始め、リストから V8 プロファイリングログの解析 を選択します。

次に、関連する V8 ログファイル isolate-<session number> を選択します。 IntelliJ IDEA は、選択したログファイルの名前で別のタブを作成します。
収集したプロファイリング データに基づいて、IntelliJ IDEA は 3 つの呼び出しツリーをビルドし、それぞれを個別のペインに表示します。 これらの呼び出しツリーを利用すると、アプリケーションの実行を 2 つの異なる視点から分析できます:一方はどの呼び出しが時間を多く消費しているか(「重い」)、もう一方は「誰が誰を呼び出したか」という関係です。
コールツリーのメトリクスを理解する
コールツリーは、関数内のティック数またはその合計実行時間に対する比率を表す 合計および セルフメトリクスを使用します。
Total は、関数内で費やされた時間とそれが呼び出した関数を示します。
Self は、子ノードを考慮せずに、関数自体の内部でのみ費やされた時間を示します。
親メトリクスは、それを呼び出した関数の実行時間に対する関数の純粋な実行時間の比(親 )を示します。
V8 オプティマイザー
場合によっては、V8 でコードを最適化できます。 詳細については、 V8 の最適化(英語)を参照してください。
機能名の前のアスタリスク
*は、その機能が最適化されたことを示します。チルダ
~は、関数が最適化を必要としている可能性があるが、最適化されていないことを示します。 コードが短期間の場合、エンジンは最適化を延期するかスキップする場合がありますが、パフォーマンスを向上させるためにコードを書き直すことができる場所をチルダで示します。
トップコールツリー
トップ呼び出し ペインには、実行されたアクティビティが セルフメトリクスでソートされた降順で一覧表示されます。 各活動について、その 合計、 合計 %、 自己 % メトリクスが表示されます。 関数呼び出しごとに、IntelliJ IDEA はファイルの名前、行、関数が定義されている列を表示します。

概要 ペインのダイアグラムは、 自己 % メトリクスが 1% を超えるコールの セルフ時間の分布を示しています。
ボトムアップツリー
ボトムアップ ペインには、 セルフメトリクスによって降順にソートされた実行済みアクティビティも一覧表示されます。 トップ呼び出し ペインとは異なり、 ボトムアップ ペインには、 合計 % メトリクスが 2 を超えるアクティビティと呼び出した関数のみが表示されます。
アクティビティごとに、 ティックでの実行時間と 親メトリクスが表示されます。
関数呼び出しごとに、IntelliJ IDEA はファイルの名前、行、関数が定義されている列を表示します。

トップダウンツリー
トップダウン ペインには、呼び出し階層全体が表示され、上部には実行エントリポイントである関数が表示されます。 各活動について、その 合計、 合計 %、 セルフ、 自己 % メトリクスが表示されます。 関数呼び出しごとに、IntelliJ IDEA はファイルの名前、行、関数が定義されている列を表示します。

コールツリーを移動する
機能のソースコードに移動するには、この機能を選択してツールバーの F4 または
を押すか、コンテキストメニューから ソースに移動 を選択します。
別のペインに切り替えて別の観点から呼び出しを調べるには、呼び出しを選択し、呼び出しのコンテキストメニューから 次に移動 を選択してから、宛先を選択します。 IntelliJ IDEA は、選択されたペインに切り替え、フォーカスを呼び出しに移動します。
ノードを展開または折りたたむ
IntelliJ IDEA がプロファイリングセッションのタブを開くと、デフォルトで最も負荷の高い呼び出しを含むノードが展開されます。 ツリーを探索しているときに、これらのノードの一部を折りたたんだり、他のノードを展開したりすることもできます。
ノードを展開または折りたたむには、そのコンテキストメニューから ノードの展開 または ノードを折りたたむ を選択します。
アクティブペイン内のすべてのノードを折りたたむには、ツールバーの
をクリックします。
元のツリー表示に戻すには、
をクリックします。
軽量な呼び出しをフィルタリングする
パフォーマンスの問題を実際に引き起こす呼び出しのみを確認するには、これを実行してください。
ツールバーの
をクリックしてから、スライダを使用して、表示される呼び出しの 合計 % または 親 % の最小値を指定し、 終了 をクリックします。
プロファイリングデータを保存して比較する
関数とそのメトリクスを含む行を保存するには、その関数のコンテキストメニューから コピー を選択します。 これは、たとえばコードを改善した後など、2 つのセッションからの関数の測定値を比較したい場合に役立ちます。
関数名とそれが定義されているファイルの名前だけを保存するには、関数のコンテキストメニューから 呼び出しのコピー を選択します。
アイテムをクリップボードの内容と比較するには、アイテムのコンテキストメニューから クリップボードと比較 を選択します。 IntelliJ IDEA は 差分ビューアーを開きます。
現在のログを他のログと比較するには、ツールバーの
をクリックします。 開いたダイアログで、現在のものと比較するためにアイソレートを選択します。 検索対象を絞り込むには、ターゲット分離株が現在の分離株の前後どちらにあるかを指定します。
コールツリーをエクスポートする
現在のペインのコールツリーをテキストファイルに保存するには、ツールバーの
をクリックして、表示されるダイアログでターゲットファイルを指定します。
フレームチャートの分析
多色 フレームチャート を使用して、アプリケーションがどこで一時停止したかを見つけ、これらの一時停止を引き起こした呼び出しを調べます。

チャートは 4 つの領域で構成されています。
上部の領域には、調査するフラグメントの先頭と最後を制限する 2 つのスライダを持つタイムラインが表示されます。
下の領域には、多色のチャートの形で呼び出しのスタックが表示されます。 最初に呼び出されると、各関数にはランダムな色が割り当てられ、現在のセッション内のこの関数のすべての呼び出しがこの色で表示されます。
中央の領域には、 ガベージコレクタからの呼び出し、エンジン、外部呼び出し、実行自体の概要が表示されます。 これらの活動のために予約されている色はエリアの上にリストされています。
右側のペインには、選択した断片内の呼び出しが一覧表示されます。各呼び出しについて、リストにはその所要時間、呼び出された関数の名前、および関数が定義されているファイルが表示されます。
下部と右側の領域は同期しています。下部領域のスライダーをタイムライン上でドラッグすると、右側のペインのフォーカスがそのとき実行されていたコールに移動します。
さらに、下部の領域でコールをクリックすると、スライダーが自動的にそのコールに移動し、右側のペインのフォーカスが対応する機能に切り替わり、必要に応じてリストが自動的にスクロールします。 逆に、リスト内の項目をクリックすると、IntelliJ IDEA は下部領域で対応するコールを選択し、スライダーを自動的にそこにドラッグします。
タイムラインでフラグメントを選択する
特定の期間内のプロセスを調べるには、タイムラインで対応するフラグメントを選択する必要があります。 これを行うには、スライダーをドラッグするか、2 つのスライダー間の ウィンドウをクリックして、必要なフラグメントまでドラッグします。
いずれの場合も、下の多色チャートは、選択したフラグメント内のコールのスタックを示しています。
チャートを拡大するには、選択したフラグメントをクリックし、ツールバーの
をクリックします。 IntelliJ IDEA は新しいタブを開き、選択したフラグメントをタブの幅に合わせて拡大して表示するため、フラグメントをより詳細に調べることができます。
フレームチャートを移動する
右側の領域の呼び出しから、呼び出された関数のソースコード、ツールウィンドウの他のペイン、特定のメトリクスを含むフレームチャート内の領域に移動できます。
呼び出された関数のソースコードに移動するには、呼び出しのコンテキストメニューから ソースに移動 を選択してください。
呼び出しの特定のメトリクスを持つフラグメントでフレームチャートを拡大するには、呼び出しを選択し、呼び出しのコンテキストメニューから 次に移動 を選択してから、メトリクスを選択します。
呼び出しのスタックトレースに移動して、例外を表示および分析することもできます。 それには、呼び出しのコンテキストメニューから スタックトレースとして表示 を選択します。 IntelliJ IDEA は別のタブでスタックトレースを開き、 フレームチャート ペインに戻るには、下部の V8 CPU プロファイリング ツールウィンドウボタンをクリックします。
メモリプロファイリング
メモリプロファイリングを使用すると、メモリリークや動的メモリの問題を検出し、引き起こしたコードの断片を見つけることができます。
メモリプロファイリングを有効にする
アプリケーション起動時にメモリスナップショットの取得を起動するには、 Node.js 実行構成で追加設定を指定する必要があります。
に移動します。 または、ツールバーの 実行 ウィジェットから 実行構成の編集 を選択します。

開いた 実行構成の編集 ダイアログで、ツールバーの 追加 ボタン (
) をクリックし、リストから Node.js を選択します。
リストから、 Node.js の実行構成を選択して CPU プロファイリングをアクティブにするか、 Node.js 実行 / デバッグ構成を作成する に従って新しいコンフィギュレーションを作成します。
V8 プロファイリング タブに切り替えて、 ヒープスナップショットの取得を許可する チェックボックスを選択します。
メモリプロファイリング情報を収集する
メインツールバーのリストから実行構成を選択して
をクリックするか、メインメニューから を選択します。
アプリケーションの実行中はいつでも、 実行 ツールウィンドウのツールバーの
をクリックします。
表示されるダイアログで、スナップショットの名前と保存先フォルダーへのパスを指定します。 スナップショットの分析をすぐに開始するには、 スナップショットを開く チェックボックスを選択します。
メモリスナップショットの分析
スナップショットを撮り、それを分析することを選択すると、IntelliJ IDEA は収集されたデータを含む V8 ヒープ ツールウィンドウを開きます。 ウィンドウがすでに開いていて別のセッションの収集データを表示している場合は、IntelliJ IDEA は新しいタブを開きます。
以前に保存したメモリプロファイリングデータを開いて分析するには、 に移動します(または Ctrl+Shift+A を押して、 V8 の入力を開始し、リストから V8 ヒープスナップショットの解析 を選択します。

次に、関連する .heapsnapshot ファイルを選択します。 IntelliJ IDEA は、選択したファイルの名前で別のタブを作成します。
ツールウィンドウには、さまざまな観点から収集された情報を表示する 3 つのタブがあります。
包含 タブでは、アプリケーション内のオブジェクトが複数の最上位エントリごとにグループ化されて表示されます: DOMWindow オブジェクト、 ネイティブ ブラウザー オブジェクト 、および GC ルート (ガーベジ コレクターが実際に使用するルート)。 詳細については、「Containment View 」を参照してください。
各オブジェクトについて、タブには GC ルートからの距離 (そのオブジェクトと GC ルート間のノードの最短単純パス)、オブジェクトの シャローサイズ 、および 保持サイズが表示されます。 オブジェクトのサイズについて絶対値だけでなく、IntelliJ IDEA はそのオブジェクトが占めているメモリーの割合も表示します。
最大オブジェクト タブには、 保持サイズでソートされた最もメモリを消費するオブジェクトが表示されます。 このタブでは、グローバルオブジェクトにデータを蓄積することによって引き起こされるメモリリークを見つけることができます。
要約 タブには、アプリケーション内のオブジェクトがタイプ別にグループ化されて表示されます。 タブには、各タイプのオブジェクトの数、サイズ、占有しているメモリの割合が表示されます。 この情報は、メモリ状態の手掛かりになる場合があります。
各タブには 詳細 ペインがあり、GC ルートから現在選択されているオブジェクトへのパスとオブジェクトの リテイナのリスト、つまり選択されたオブジェクトへのリンクを保持するオブジェクトが表示されます。 すべてのヒープスナップショットには多くの「バック」参照とループがあるため、オブジェクトごとに多数のリテイナーが常に存在します。
オブジェクトにテキストラベルを付ける
ラベルを使用すると、コンテキストを失わずにオブジェクトを区別したり、オブジェクトを移動したりできます。
オブジェクトにラベルを設定するには、オブジェクトを選択してツールバーの
をクリックするか、コンテキストメニューから マーク を選択します。 次に開いたダイアログでテキストラベルを指定します。
スナップショットを移動する
オブジェクトに対応する関数または変数に移動するには、このオブジェクトを選択してツールバーの
をクリックするか、コンテキストメニューから ソースの編集 を選択します。 ボタンとメニューオプションが無効になっている場合、これは IntelliJ IDEA が選択されたオブジェクトに対応する機能や変数を見つけられなかったことを意味します。
複数の関数または変数が見つかった場合、IntelliJ IDEA はそれらを候補リストに表示します。
封じ込めの観点からオブジェクトを調べ、オブジェクト間のリンクに集中できるように、IntelliJ IDEA では、 最大オブジェクト または 要約 タブまたは 出現箇所 ビューのオブジェクトから 包含 タブの同じオブジェクトに移動できます。
これを行うには、オブジェクトを選択し、コンテキストメニューから メインツリー内の移動 を選択します。
スナップショットを検索する
包含 タブで、ツールバーの
をクリックします。
表示される V8 ヒープ検索 ダイアログで、検索パターンと検索範囲を指定します。 使用可能な範囲は次のとおりです。
すべての場所: すべてのスコープで検索するには、このチェックボックスを選択してください。 このチェックボックスを選択すると、他の検索タイプはすべて無効になります。
リンク名: C++ ランタイムを呼び出すときに V8 が作成するオブジェクト名の中から検索するには、このチェックボックスを選択します。
V8 ヒープ ツールウィンドウでは、リンク名は
%文字%<link name>でマークされています。クラス名:: このチェックボックスを選択すると、関数コンストラクターを検索できます。
テキスト文字列: このチェックボックスを選択すると、オブジェクトの内容でテキスト検索が実行されます。
スナップショットのオブジェクト ID: このチェックボックスを選択すると、オブジェクトの一意の識別子を検索できます。 V8 は、オブジェクトが作成されるときにその形式でそのような固有の ID を各オブジェクトに割り当て、オブジェクトが破棄されるまでそれを保存します。 つまり、同じセッション内で作成された複数のスナップショットで同じオブジェクトを見つけて比較することができます。
V8 ヒープ ツールウィンドウでは、オブジェクト ID は
@文字@<object id>でマークされています。マーク: このチェックボックスを選択して、 包含 タブのツールバーの
をクリックして、オブジェクトに手動で設定したラベルを検索します。
検索結果は、 詳細 ペインに別の '<search pattern>' の出現 ビューで表示されます。 指定した検索範囲で検索結果をグループ化して表示するには、ツールバーの タイプ別にグループ化 トグルボタンを押します。
次回ダイアログを開くと、前回の検索の設定が表示されます。