メモリ用語
メモリ ツールでは 、メモリの問題を調査するために、次の用語が使用されます。 これらのメモリ用語は、一般的なメモリ分析だけでなく、Java や .NET などの言語のメモリ プロファイル ツールにも適用されます。
メモリ ツールの使用方法の詳細については、「メモリツールを使用してヒープ スナップショットを記録する ("ヒープ スナップショット" プロファイルの種類)」を参照してください。
メモリ グラフ
Web ページで使用されるメモリをグラフと考えます。エッジで接続されているノードを含む構造です。
メモリ グラフ内のノードは、JavaScript 番号や文字列などのプリミティブ型、連想配列などのオブジェクトなど、ページで使用されるオブジェクトを表します。 メモリ グラフ内のノードとエッジには、次のラベルが付けられます。
ノード (または オブジェクト) は、それらをビルドするために使用された コンストラクター 関数の名前を使用してラベル付けされます。
エッジ には 、プロパティの名前を使用してラベルが付けられます。
グラフ内のノードは、次の 2 つの方法でメモリを保持できます。
直に;メモリはオブジェクト自体によって保持されます。
暗黙的に、他のオブジェクトへの参照を保持します。 他のオブジェクトへの参照を保持しているオブジェクトは、それらのオブジェクトがガベージ コレクション (GC) によって自動的に破棄されるのを防ぎます。
JavaScript ヒープとレンダラー メモリ
JavaScript ヒープは、すべての JavaScript オブジェクトと WebAssembly オブジェクトが住んでいるブラウザー プロセスのメモリ領域です。 JavaScript ヒープは、(Microsoft Edge をサポートする V8 JavaScript エンジンの後に) V8 メモリ とも呼ばれます。
JavaScript ヒープはレンダラー メモリの一部です。 レンダラー メモリは、Web ページがレンダリングされるブラウザー プロセスで使用されるメモリです。 レンダラー メモリは、次で構成されます。
- DOM ノードを表す C++ オブジェクトによって使用されるメモリなどのネイティブ メモリ。
- ページの JavaScript ヒープ メモリ。
- ページによって開始されるすべての専用ワーカーの JavaScript ヒープ メモリ。
メモリ ツールには、次の両方が表示されます。
- V8 メモリ。
- レンダリングされた Web ページに関連するネイティブ メモリに割り当てられたオブジェクト。
ガベージ コレクション ルート
ガベージ コレクション ルート (GC ルート) は、ブラウザーのネイティブ コードから V8 仮想マシンの外部にある JavaScript オブジェクトへの参照が行われると、ブラウザーによって作成されます。 これらの参照は ハンドルと呼ばれます。
内部 GC ルートは多数ありますが、そのほとんどは Web 開発者にとって興味深くはありません。 Web ページの観点から、次の種類の GC ルートが存在します。
ウィンドウ グローバル オブジェクト (各 iframe に 1 つ)。
オブジェクトは、コンソール ツールで JavaScript 式を評価する場合など、ソースまたはコンソール ツールによって設定されるデバッグ コンテキストによって保持される場合があります。 メモリ ツールからこれらのオブジェクトを削除するには、ヒープ スナップショットを記録する前に、コンソール ツールをクリアし、[ソース] ツールでブレークポイントを非アクティブ化します。
メモリ グラフは GC ルートで始まります。これは、ブラウザーの window
オブジェクトか、Node.js モジュールの Global
オブジェクトです。 ルート オブジェクトのガベージ コレクション方法は制御しません。
ルートから到達できないノードは、ガベージ コレクションを取得できます。
オブジェクトのサイズと距離
メモリ ツールには、次の情報列が表示されます。
- [距離] 列
- [浅いサイズ] 列
- [保持サイズ] 列
これらの列については、以下で説明します。
Distance
JavaScript ヒープ内のオブジェクトの 距離 は、オブジェクトと GC ルートの間の最短パス上のノードの数です。 距離が短いほど、このオブジェクトが Web ページのメモリ使用量において重要な役割を果たす可能性が高くなります。
浅いサイズ
浅いサイズは、オブジェクトによって直接保持される JavaScript ヒープのサイズです。 JavaScript オブジェクトは、オブジェクトの直接保持されたメモリに値ではなく、オブジェクトの説明のみを格納するため、通常、オブジェクトの浅いサイズは小さくなります。 ほとんどの JavaScript オブジェクトは、JavaScript ヒープ内の他の場所にある バッキング ストア に値を格納し、オブジェクトが直接所有する JavaScript ヒープの部分にのみ小さなラッパー オブジェクトを公開します。
ただし、小さなオブジェクトでも、ガベージ コレクション プロセスによって他のオブジェクトが破棄されないようにすることで、大量のメモリを 間接的に保持できます。
[浅いサイズ] 列の数値はバイト数です。
保持サイズ
保持サイズは、オブジェクトによって暗黙的に保持されるメモリのサイズであり、GC ルートから到達できないすべての依存オブジェクトと共にオブジェクトとその他の既存のリテーナーが削除されると解放される可能性があります。
つまり、オブジェクトの保持サイズは、オブジェクトとその依存オブジェクトがすべてメモリ グラフから削除された場合に取り戻されるメモリの量です。
保持サイズを浅いサイズより小さくすることはできません。
オブジェクトが複数のノードによって保持されている場合、オブジェクトのサイズは、GC ルートへの最短パスを持つ保持ノードの保持サイズに表示されます。
[保持サイズ] 列の数値はバイト数です。
家臣
オブジェクトの リテーナー は、オブジェクトへの参照を保持する他のオブジェクトです。 メモリ ツールの [保持者] セクションには、[概要] ビューで選択したオブジェクトへの参照を保持するオブジェクトが表示されます。
メモリ ツールの [リテーナー] セクションは、既定では距離で並べ替えられます。つまり、オブジェクトの最も単純な保持パスが最初に表示されます。
リテーナーを持たないオブジェクトは、ブラウザーのガベージ コレクターによって破棄され、メモリ使用量が削減されます。
V8 の詳細
メモリをプロファイリングするときは、ヒープ スナップショットが特定の方法で表示される理由を理解すると便利です。 このセクションでは、メモリ ツールでヒープ スナップショットを分析する際に役立つ、 V8 JavaScript 仮想マシン (ここでは V8 VM、または VM のみと省略) によって一部のオブジェクトが メモリ に格納される方法について説明します。
JavaScript プリミティブ
JavaScript には、次のようないくつかのプリミティブ型があります。
- 数値 (
3.14159
など)。 - ブール値 (
true
またはfalse
)。 - 文字列 (
"Werner Heisenberg"
など)。
プリミティブは他の値を参照できず、メモリ グラフでは常にリーフ ノード ( 終端ノードとも呼ばれます) になります。
数値 は、次のいずれかとして格納できます。
小さな整数 (SMI) と呼ばれる即時の 31 ビット整数値。
ヒープ オブジェクト。 ヒープ番号と呼ばれます。 ヒープ番号は、
double
型の値など、小整数 (SMI) フォームに収まらない値を格納したり、値をボックス化する必要がある場合 (プロパティの設定など) に使用されます。
文字列 は、次のいずれかに格納できます。
VM ヒープ。
レンダラーのメモリ内 の外部。 ラッパー オブジェクトが作成され、外部ストレージにアクセスするために使用されます。たとえば、スクリプト ソースや Web から受信したその他のコンテンツは、VM ヒープにコピーされるのではなく、格納されます。
JavaScript オブジェクト
新しい JavaScript オブジェクトのメモリは、専用の JavaScript ヒープ (または VM ヒープ) から割り当てられます。 これらのオブジェクトは V8 VM のガベージ コレクターによって管理されるため、これらのオブジェクトへの参照が少なくとも 1 つ存在する限り、これらのオブジェクトは存続します。
その他のオブジェクト
ネイティブ オブジェクト: JavaScript ヒープに格納されていないものは、 ネイティブ オブジェクトと呼ばれます。 ヒープ オブジェクトとは対照的に、ネイティブ オブジェクトは、有効期間を通じて V8 ガベージ コレクターによって管理されるものではなく、JavaScript ラッパー オブジェクトを使用して JavaScript からのみアクセスできます。
連結文字列: JavaScript での文字列連結の結果として、格納されて結合される文字列は、連結 された文字列 として V8 に格納されます。 文字列の内容の結合は、結合された文字列の部分文字列を構築する必要がある場合など、必要に応じてのみ発生します。
たとえば、
a
とb
を連結すると、連結の結果を表す連結文字列(a, b)
が取得されます。 後でc
をその結果と連結すると、別の連結文字列 (((a, b), c)
) が取得されます。配列: 配列 は、数値キーを持つオブジェクトです。 配列は、大量のデータを格納するために V8 VM で広く使用されます。 ディクショナリのように使用されるキーと値のペアのセットは、配列として実装されます。
一般的な JavaScript オブジェクトは、次の 2 つの配列型のうちの 1 つだけとして格納されます。
- 名前付きプロパティを格納するための配列。
- 数値要素を格納するための配列。
プロパティの数が少ない場合、プロパティは JavaScript オブジェクトに内部的に格納されます。
system/ Map: オブジェクトの種類とレイアウトの両方を記述するオブジェクト。 たとえば、 システム/マップ オブジェクトは、高速プロパティ アクセスの暗黙的なオブジェクト階層を記述するために使用されます。 「V8 の高速プロパティ」を参照してください。
注:
このページの一部は、 Google によって 作成および共有され、 クリエイティブ・コモンズ属性 4.0 国際ライセンスに記載されている条件に従って使用される作業に基づく変更です。 元のページは ここに あり、Meggin Kearney によって作成されています。