V8#

ソースコード: lib/v8.js

node:v8 モジュールは、Node.js バイナリに組み込まれた V8 のバージョンに固有の API を公開します。アクセスするには、次を使用します。

const v8 = require('node:v8'); 

v8.cachedDataVersionTag()#

V8 のバージョン、コマンドラインフラグ、および検出された CPU 機能から派生したバージョンタグを表す整数を返します。これは、vm.Script cachedData バッファがこの V8 インスタンスと互換性があるかどうかを判断するのに役立ちます。

console.log(v8.cachedDataVersionTag()); // 3947234607
// The value returned by v8.cachedDataVersionTag() is derived from the V8
// version, command-line flags, and detected CPU features. Test that the value
// does indeed update when flags are toggled.
v8.setFlagsFromString('--allow_natives_syntax');
console.log(v8.cachedDataVersionTag()); // 183726201 

v8.getHeapCodeStatistics()#

ヒープ内のコードとそのメタデータに関する統計情報を取得します。V8 の GetHeapCodeAndMetadataStatistics API を参照してください。次のプロパティを持つオブジェクトを返します。

{
  code_and_metadata_size: 212208,
  bytecode_and_metadata_size: 161368,
  external_script_source_size: 1410794,
  cpu_profiler_metadata_size: 0,
} 

v8.getHeapSnapshot([options])#

  • options <Object>

    • exposeInternals <boolean> true の場合、ヒープスナップショットで内部を公開します。 デフォルト: false.
    • exposeNumericValues <boolean> true の場合、数値を人工フィールドに公開します。 デフォルト: false.
  • 戻り値: <stream.Readable> V8 ヒープスナップショットを含む Readable。

現在の V8 ヒープのスナップショットを生成し、JSON シリアライズされた表現を読み取るために使用できる Readable ストリームを返します。この JSON ストリーム形式は、Chrome DevTools などのツールで使用することを目的としています。JSON スキーマは文書化されておらず、V8 エンジンに固有です。したがって、スキーマは V8 のバージョンによって変更される可能性があります。

ヒープスナップショットを作成するには、スナップショットの作成時のヒープサイズの約 2 倍のメモリが必要です。そのため、OOM キラーによってプロセスが終了するリスクがあります。

スナップショットの生成は同期操作であり、ヒープサイズに応じてイベントループを一定期間ブロックします。

// Print heap snapshot to the console
const v8 = require('node:v8');
const stream = v8.getHeapSnapshot();
stream.pipe(process.stdout); 

v8.getHeapSpaceStatistics()#

V8 ヒープスペース、つまり V8 ヒープを構成するセグメントに関する統計情報を返します。ヒープスペースの順序も、ヒープスペースの可用性も保証されません。統計情報は V8 の GetHeapSpaceStatistics 関数によって提供され、V8 のバージョンによって変更される可能性があります。

返される値は、次のプロパティを含むオブジェクトの配列です。

[
  {
    "space_name": "new_space",
    "space_size": 2063872,
    "space_used_size": 951112,
    "space_available_size": 80824,
    "physical_space_size": 2063872
  },
  {
    "space_name": "old_space",
    "space_size": 3090560,
    "space_used_size": 2493792,
    "space_available_size": 0,
    "physical_space_size": 3090560
  },
  {
    "space_name": "code_space",
    "space_size": 1260160,
    "space_used_size": 644256,
    "space_available_size": 960,
    "physical_space_size": 1260160
  },
  {
    "space_name": "map_space",
    "space_size": 1094160,
    "space_used_size": 201608,
    "space_available_size": 0,
    "physical_space_size": 1094160
  },
  {
    "space_name": "large_object_space",
    "space_size": 0,
    "space_used_size": 0,
    "space_available_size": 1490980608,
    "physical_space_size": 0
  }
] 

v8.getHeapStatistics()#

次のプロパティを持つオブジェクトを返します。

does_zap_garbage は 0/1 のブール値で、--zap_code_space オプションが有効かどうかを示します。これにより、V8 はヒープのガベージをビットパターンで上書きします。RSS フットプリント(常駐セットサイズ)は、すべてのヒープページに継続的にアクセスするため大きくなり、オペレーティングシステムによってスワップアウトされる可能性が低くなります。

number_of_native_contexts native_context の値は、現在アクティブなトップレベルコンテキストの数です。この数値が時間の経過とともに増加すると、メモリリークが発生していることを示します。

number_of_detached_contexts detached_context の値は、デタッチされ、まだガベージコレクションされていないコンテキストの数です。この数値がゼロ以外の場合、潜在的なメモリリークが発生していることを示します。

total_global_handles_size total_global_handles_size の値は、V8 グローバルハンドルの合計メモリサイズです。

used_global_handles_size used_global_handles_size の値は、使用されている V8 グローバルハンドルのメモリサイズです。

external_memory external_memory の値は、配列バッファと外部文字列のメモリサイズです。

{
  total_heap_size: 7326976,
  total_heap_size_executable: 4194304,
  total_physical_size: 7326976,
  total_available_size: 1152656,
  used_heap_size: 3476208,
  heap_size_limit: 1535115264,
  malloced_memory: 16384,
  peak_malloced_memory: 1127496,
  does_zap_garbage: 0,
  number_of_native_contexts: 1,
  number_of_detached_contexts: 0,
  total_global_handles_size: 8192,
  used_global_handles_size: 3296,
  external_memory: 318824
} 

v8.setFlagsFromString(flags)#

v8.setFlagsFromString()メソッドは、プログラムでV8コマンドラインフラグを設定するために使用できます。このメソッドは注意して使用する必要があります。VMの起動後に設定を変更すると、クラッシュやデータの損失など、予期しない動作が発生する可能性があります。あるいは、単に何も起こらない可能性もあります。

特定のバージョンのNode.jsで使用可能なV8オプションは、node --v8-optionsを実行することで確認できます。

使用方法

// Print GC events to stdout for one minute.
const v8 = require('node:v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3); 

v8.stopCoverage()#

v8.stopCoverage()メソッドを使用すると、NODE_V8_COVERAGEによって開始されたカバレッジコレクションを停止できます。これにより、V8は実行カウントレコードを解放し、コードを最適化できます。ユーザーがオンデマンドでカバレッジを収集したい場合は、v8.takeCoverage()と組み合わせて使用​​できます。

v8.takeCoverage()#

v8.takeCoverage()メソッドを使用すると、NODE_V8_COVERAGEによって開始されたカバレッジをオンデマンドでディスクに書き込むことができます。このメソッドは、プロセスのライフタイム中に複数回呼び出すことができます。呼び出すたびに実行カウンターがリセットされ、NODE_V8_COVERAGEで指定されたディレクトリに新しいカバレッジレポートが書き込まれます。

プロセスが終了しようとしているとき、プロセスが終了する前にv8.stopCoverage()が呼び出されない限り、最後のカバレッジがディスクに書き込まれます。

v8.writeHeapSnapshot([filename[,options]])#

  • filename <string> V8ヒープスナップショットを保存するファイルパス。指定しない場合、'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot'のパターンを持つファイル名が生成されます。ここで、{pid}はNode.jsプロセスのPID、{thread_id}は、writeHeapSnapshot()がNode.jsのメインスレッドから呼び出された場合は0、ワーカースレッドから呼び出された場合はワーカースレッドのIDになります。
  • options <Object>
    • exposeInternals <boolean> true の場合、ヒープスナップショットで内部を公開します。 デフォルト: false.
    • exposeNumericValues <boolean> true の場合、数値を人工フィールドに公開します。 デフォルト: false.
  • 戻り値: <string> スナップショットが保存されたファイル名。

現在のV8ヒープのスナップショットを生成し、JSONファイルに書き込みます。このファイルは、Chrome DevToolsなどのツールで使用することを目的としています。JSONスキーマは文書化されておらず、V8エンジンに固有のものであり、V8のバージョンによって変更される可能性があります。

ヒープスナップショットは、単一のV8分離環境に固有のものです。ワーカースレッドを使用する場合、メインスレッドから生成されたヒープスナップショットには、ワーカーに関する情報は含まれず、その逆も同様です。

ヒープスナップショットを作成するには、スナップショットの作成時のヒープサイズの約 2 倍のメモリが必要です。そのため、OOM キラーによってプロセスが終了するリスクがあります。

スナップショットの生成は同期操作であり、ヒープサイズに応じてイベントループを一定期間ブロックします。

const { writeHeapSnapshot } = require('node:v8');
const {
  Worker,
  isMainThread,
  parentPort,
} = require('node:worker_threads');

if (isMainThread) {
  const worker = new Worker(__filename);

  worker.once('message', (filename) => {
    console.log(`worker heapdump: ${filename}`);
    // Now get a heapdump for the main thread.
    console.log(`main thread heapdump: ${writeHeapSnapshot()}`);
  });

  // Tell the worker to create a heapdump.
  worker.postMessage('heapdump');
} else {
  parentPort.once('message', (message) => {
    if (message === 'heapdump') {
      // Generate a heapdump for the worker
      // and return the filename to the parent.
      parentPort.postMessage(writeHeapSnapshot());
    }
  });
} 

v8.setHeapSnapshotNearHeapLimit(limit)#

安定性: 1 - 実験的

--heapsnapshot-near-heap-limitがすでにコマンドラインから設定されている場合、またはAPIが複数回呼び出された場合、APIは何もしません。 limitは正の整数である必要があります。詳細については、--heapsnapshot-near-heap-limitを参照してください。

シリアライゼーションAPI#

シリアライゼーションAPIは、HTML構造化クローンアルゴリズムと互換性のある方法でJavaScript値をシリアライズする手段を提供します。

フォーマットは下位互換性があります(つまり、ディスクに保存しても安全です)。等しいJavaScript値が異なるシリアライズ出力になる場合があります。

v8.serialize(value)#

DefaultSerializerを使用して、valueをバッファにシリアライズします。

ERR_BUFFER_TOO_LARGEは、buffer.constants.MAX_LENGTHより大きいバッファを必要とする巨大なオブジェクトをシリアライズしようとするとスローされます。

v8.deserialize(buffer)#

デフォルトオプションのDefaultDeserializerを使用して、バッファからJS値を読み取ります。

クラス: v8.Serializer#

new Serializer()#

新しいSerializerオブジェクトを作成します。

serializer.writeHeader()#

シリアライゼーションフォーマットバージョンを含むヘッダーを書き込みます。

serializer.writeValue(value)#

JavaScript値をシリアライズし、シリアライズされた表現を内部バッファに追加します。

valueをシリアライズできない場合、これはエラーをスローします。

serializer.releaseBuffer()#

格納されている内部バッファを返します。バッファが解放されたら、このシリアライザーを使用しないでください。前回の書き込みに失敗した場合、このメソッドを呼び出すと未定義の動作が発生します。

serializer.transferArrayBuffer(id, arrayBuffer)#

ArrayBufferの内容が帯域外に転送されたことをマークします。対応するArrayBufferを逆シリアル化コンテキストでdeserializer.transferArrayBuffer()に渡します。

serializer.writeUint32(value)#

生の32ビット符号なし整数を書き込みます。カスタムのserializer._writeHostObject()内で使用します。

serializer.writeUint64(hi, lo)#

高位と低位の32ビット部分に分割された生の64ビット符号なし整数を書き込みます。カスタムのserializer._writeHostObject()内で使用します。

serializer.writeDouble(value)#

JSのnumber値を書き込みます。カスタムのserializer._writeHostObject()内で使用します。

serializer.writeRawBytes(buffer)#

シリアライザーの内部バッファに生のバイトを書き込みます。デシリアライザーは、バッファの長さを計算する方法が必要です。カスタムのserializer._writeHostObject()内で使用します。

serializer._writeHostObject(object)#

このメソッドは、ネイティブC ++バインディングによって作成されたオブジェクトなど、ある種のホストオブジェクトを書き込むために呼び出されます。 objectをシリアライズできない場合は、適切な例外をスローする必要があります。

このメソッドは、Serializerクラス自体には存在しませんが、サブクラスによって提供できます。

serializer._getDataCloneError(message)#

このメソッドは、オブジェクトを複製できないときにスローされるエラーオブジェクトを生成するために呼び出されます。

このメソッドはデフォルトでErrorコンストラクターに設定されており、サブクラスでオーバーライドできます。

serializer._getSharedArrayBufferId(sharedArrayBuffer)#

このメソッドは、シリアライザがSharedArrayBufferオブジェクトをシリアル化しようとする際に呼び出されます。このメソッドは、オブジェクトに対して符号なし32ビット整数IDを返さなければなりません。このSharedArrayBufferが既にシリアル化されている場合は、同じIDを使用します。デシリアライズするとき、このIDはdeserializer.transferArrayBuffer()に渡されます。

オブジェクトをシリアル化できない場合は、例外をスローする必要があります。

このメソッドは、Serializerクラス自体には存在しませんが、サブクラスによって提供できます。

serializer._setTreatArrayBufferViewsAsHostObjects(flag)#

TypedArrayおよびDataViewオブジェクトをホストオブジェクトとして扱うかどうか、つまりserializer._writeHostObject()に渡すかどうかを指定します。

クラス: v8.Deserializer#

new Deserializer(buffer)#

新しいDeserializerオブジェクトを作成します。

deserializer.readHeader()#

ヘッダー(フォーマットバージョンを含む)を読み取って検証します。例えば、無効またはサポートされていないワイヤフォーマットを拒否する場合があります。その場合、Errorがスローされます。

deserializer.readValue()#

バッファからJavaScriptの値をデシリアライズして返します。

deserializer.transferArrayBuffer(id, arrayBuffer)#

ArrayBufferの内容が帯域外に転送されたことをマークします。対応するArrayBufferをシリアル化コンテキストでserializer.transferArrayBuffer()に渡します(または、SharedArrayBufferの場合、serializer._getSharedArrayBufferId()からidを返します)。

deserializer.getWireFormatVersion()#

基盤となるワイヤフォーマットバージョンを読み取ります。おそらく、古いワイヤフォーマットバージョンを読み取るレガシーコードに役立ちます。 .readHeader()の前に呼び出すことはできません。

deserializer.readUint32()#

生の32ビット符号なし整数を読み取って返します。カスタムdeserializer._readHostObject()内で使用します。

deserializer.readUint64()#

生の64ビット符号なし整数を読み取り、2つの32ビット符号なし整数エントリを持つ配列[hi, lo]として返します。カスタムdeserializer._readHostObject()内で使用します。

deserializer.readDouble()#

JSのnumber値を読み取ります。カスタムdeserializer._readHostObject()内で使用します。

deserializer.readRawBytes(length)#

デシリアライザの内部バッファから生のバイトを読み取ります。 lengthパラメータは、serializer.writeRawBytes()に渡されたバッファの長さに対応している必要があります。カスタムdeserializer._readHostObject()内で使用します。

deserializer._readHostObject()#

このメソッドは、ある種のホストオブジェクト、つまりネイティブC++バインディングによって作成されたオブジェクトを読み取るために呼び出されます。データをデシリアライズできない場合は、適切な例外をスローする必要があります。

このメソッドは、Deserializerクラス自体には存在しませんが、サブクラスによって提供できます。

クラス: v8.DefaultSerializer#

Serializerのサブクラスであり、TypedArray(特にBuffer)およびDataViewオブジェクトをホストオブジェクトとしてシリアル化し、基盤となるArrayBufferのうち、それらが参照している部分のみを格納します。

クラス: v8.DefaultDeserializer#

Deserializerのサブクラスであり、DefaultSerializerによって書き込まれたフォーマットに対応します。

Promiseフック#

promiseHooksインターフェースを使用すると、Promiseのライフサイクルイベントを追跡できます。_すべて_の非同期アクティビティを追跡するには、async_hooksを参照してください。これは、他の非同期リソースのイベントに加えて、Promiseのライフサイクルイベントを生成するために、このモジュールを内部的に使用します。リクエストコンテキスト管理については、AsyncLocalStorageを参照してください。

import { promiseHooks } from 'node:v8';

// There are four lifecycle events produced by promises:

// The `init` event represents the creation of a promise. This could be a
// direct creation such as with `new Promise(...)` or a continuation such
// as `then()` or `catch()`. It also happens whenever an async function is
// called or does an `await`. If a continuation promise is created, the
// `parent` will be the promise it is a continuation from.
function init(promise, parent) {
  console.log('a promise was created', { promise, parent });
}

// The `settled` event happens when a promise receives a resolution or
// rejection value. This may happen synchronously such as when using
// `Promise.resolve()` on non-promise input.
function settled(promise) {
  console.log('a promise resolved or rejected', { promise });
}

// The `before` event runs immediately before a `then()` or `catch()` handler
// runs or an `await` resumes execution.
function before(promise) {
  console.log('a promise is about to call a then handler', { promise });
}

// The `after` event runs immediately after a `then()` handler runs or when
// an `await` begins after resuming from another.
function after(promise) {
  console.log('a promise is done calling a then handler', { promise });
}

// Lifecycle hooks may be started and stopped individually
const stopWatchingInits = promiseHooks.onInit(init);
const stopWatchingSettleds = promiseHooks.onSettled(settled);
const stopWatchingBefores = promiseHooks.onBefore(before);
const stopWatchingAfters = promiseHooks.onAfter(after);

// Or they may be started and stopped in groups
const stopHookSet = promiseHooks.createHook({
  init,
  settled,
  before,
  after,
});

// To stop a hook, call the function returned at its creation.
stopWatchingInits();
stopWatchingSettleds();
stopWatchingBefores();
stopWatchingAfters();
stopHookSet(); 

promiseHooks.onInit(init)#

initフックはプレーン関数でなければなりません。非同期関数を指定すると、無限のマイクロタスクループが生成されるため、スローされます。

import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onInit((promise, parent) => {});const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onInit((promise, parent) => {});

promiseHooks.onSettled(settled)#

settledフックはプレーン関数でなければなりません。非同期関数を指定すると、無限のマイクロタスクループが生成されるため、スローされます。

import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onSettled((promise) => {});const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onSettled((promise) => {});

promiseHooks.onBefore(before)#

beforeフックはプレーン関数でなければなりません。非同期関数を指定すると、無限のマイクロタスクループが生成されるため、スローされます。

import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onBefore((promise) => {});const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onBefore((promise) => {});

promiseHooks.onAfter(after)#

afterフックはプレーン関数でなければなりません。非同期関数を指定すると、無限のマイクロタスクループが生成されるため、スローされます。

import { promiseHooks } from 'node:v8';

const stop = promiseHooks.onAfter((promise) => {});const { promiseHooks } = require('node:v8');

const stop = promiseHooks.onAfter((promise) => {});

promiseHooks.createHook(callbacks)#

フックコールバックはプレーン関数でなければなりません。非同期関数を指定すると、無限のマイクロタスクループが生成されるため、スローされます。

各Promiseのさまざまなライフタイムイベントに対して呼び出される関数を登録します。

コールバックinit()/before()/after()/settled()は、Promiseのライフタイム中にそれぞれのイベントに対して呼び出されます。

すべてのコールバックはオプションです。例えば、Promiseの作成のみを追跡する必要がある場合は、initコールバックのみを渡す必要があります。 callbacksに渡すことができるすべての関数の詳細は、フックコールバックセクションにあります。

import { promiseHooks } from 'node:v8';

const stopAll = promiseHooks.createHook({
  init(promise, parent) {},
});const { promiseHooks } = require('node:v8');

const stopAll = promiseHooks.createHook({
  init(promise, parent) {},
});

フックコールバック#

Promiseのライフタイムにおける重要なイベントは、Promiseの作成、継続ハンドラが呼び出される前/後またはawait前後、Promiseが解決または拒否されたときの4つの領域に分類されています。

これらのフックはasync_hooksのフックと似ていますが、destroyフックがありません。他のタイプの非同期リソースは、通常、ソケットまたはファイル記述子を表し、Promiseがコードから到達できる限り使用可能なままであるのに対し、destroyライフサイクルイベントを表す明確な「クローズ」状態を持ちます。ガベージコレクション追跡は、Promiseをasync_hooksイベントモデルに適合させるために使用されますが、この追跡は非常にコストがかかり、必ずしもガベージコレクションされるとは限りません。

Promiseは、ライフサイクルがPromiseフックメカニズムによって追跡される非同期リソースであるため、init()before()after()、およびsettled()コールバックは、無限ループを生成するより多くのPromiseを作成するため、非同期関数であってはなりません。

このAPIはPromiseイベントをasync_hooksにフィードするために使用されますが、これら2つのAPI間の順序は未定義です。両方のAPIはマルチテナントであるため、互いに相対的な順序でイベントを生成する可能性があります。

init(promise, parent)#
  • promise <Promise> 作成中のPromiseです。
  • parent <Promise> 継続元のPromise(該当する場合)。

Promiseが構築されたときに呼び出されます。これは、対応するbefore/afterイベントが発生することを意味するのではなく、可能性が存在することを意味します。これは、継続を取得することなくPromiseが作成された場合に発生します。

before(promise)#

Promiseの継続が実行される前に呼び出されます。これは、then()catch()、またはfinally()ハンドラー、あるいは再開するawaitの形式をとることができます。

beforeコールバックは0からN回呼び出されます。Promiseに対して継続が行われなかった場合、beforeコールバックは通常0回呼び出されます。同じPromiseから多くの継続が行われた場合、beforeコールバックは何度も呼び出される可能性があります。

after(promise)#

Promiseの継続が実行された直後に呼び出されます。これは、then()catch()、またはfinally()ハンドラーの後、あるいは別のawaitの後のawaitの前になる場合があります。

settled(promise)#

Promiseが解決または拒否値を受け取ったときに呼び出されます。これは、Promise.resolve()またはPromise.reject()の場合、同期的に発生する可能性があります。

スタートアップスナップショットAPI#

安定性: 1 - 実験的

v8.startupSnapshotインターフェースは、カスタムスタートアップスナップショットのシリアライズおよびデシリアライズフックを追加するために使用できます。

$ node --snapshot-blob snapshot.blob --build-snapshot entry.js
# This launches a process with the snapshot
$ node --snapshot-blob snapshot.blob 

上記の例では、entry.jsv8.startupSnapshotインターフェースのメソッドを使用して、シリアライズ中にスナップショット内のカスタムオブジェクトの情報を保存する方法、およびデシリアライズ中にその情報を使用してこれらのオブジェクトを同期する方法を指定できます。たとえば、entry.jsに次のスクリプトが含まれている場合

'use strict';

const fs = require('node:fs');
const zlib = require('node:zlib');
const path = require('node:path');
const assert = require('node:assert');

const v8 = require('node:v8');

class BookShelf {
  storage = new Map();

  // Reading a series of files from directory and store them into storage.
  constructor(directory, books) {
    for (const book of books) {
      this.storage.set(book, fs.readFileSync(path.join(directory, book)));
    }
  }

  static compressAll(shelf) {
    for (const [ book, content ] of shelf.storage) {
      shelf.storage.set(book, zlib.gzipSync(content));
    }
  }

  static decompressAll(shelf) {
    for (const [ book, content ] of shelf.storage) {
      shelf.storage.set(book, zlib.gunzipSync(content));
    }
  }
}

// __dirname here is where the snapshot script is placed
// during snapshot building time.
const shelf = new BookShelf(__dirname, [
  'book1.en_US.txt',
  'book1.es_ES.txt',
  'book2.zh_CN.txt',
]);

assert(v8.startupSnapshot.isBuildingSnapshot());
// On snapshot serialization, compress the books to reduce size.
v8.startupSnapshot.addSerializeCallback(BookShelf.compressAll, shelf);
// On snapshot deserialization, decompress the books.
v8.startupSnapshot.addDeserializeCallback(BookShelf.decompressAll, shelf);
v8.startupSnapshot.setDeserializeMainFunction((shelf) => {
  // process.env and process.argv are refreshed during snapshot
  // deserialization.
  const lang = process.env.BOOK_LANG || 'en_US';
  const book = process.argv[1];
  const name = `${book}.${lang}.txt`;
  console.log(shelf.storage.get(name));
}, shelf); 

結果のバイナリは、起動時にスナップショットからデシリアライズされたデータを出力し、起動されたプロセスの更新されたprocess.envprocess.argvを使用します。

$ BOOK_LANG=es_ES node --snapshot-blob snapshot.blob book1
# Prints content of book1.es_ES.txt deserialized from the snapshot. 

現在、ユーザーランドスナップショットからデシリアライズされたアプリケーションは再びスナップショットを取得できないため、これらのAPIはユーザーランドスナップショットからデシリアライズされていないアプリケーションでのみ使用できます。

v8.startupSnapshot.addSerializeCallback(callback[, data])#

  • callback <Function> シリアライズ前に呼び出されるコールバック。
  • data <any> コールバックが呼び出されたときにコールバックに渡されるオプションデータ。

Node.jsインスタンスがスナップショットにシリアライズされて終了しようとしているときに呼び出されるコールバックを追加します。これは、シリアライズすべきでない、またはできないリソースを解放したり、ユーザーデータをシリアライズに適した形式に変換したりするために使用できます。

コールバックは、追加された順序で実行されます。

v8.startupSnapshot.addDeserializeCallback(callback[, data])#

  • callback <Function> スナップショットがデシリアライズされた後に呼び出されるコールバック。
  • data <any> コールバックが呼び出されたときにコールバックに渡されるオプションデータ。

Node.jsインスタンスがスナップショットからデシリアライズされたときに呼び出されるコールバックを追加します。 callbackdata(提供されている場合)はスナップショットにシリアライズされ、アプリケーションの状態を再初期化したり、スナップショットからアプリケーションが再起動されたときにアプリケーションが必要とするリソースを再取得したりするために使用できます。

コールバックは、追加された順序で実行されます。

v8.startupSnapshot.setDeserializeMainFunction(callback[, data])#

  • callback <Function> スナップショットのデシリアライズ後、エントリポイントとして呼び出されるコールバック。
  • data <any> コールバックが呼び出されたときにコールバックに渡されるオプションデータ。

これは、スナップショットからデシリアライズされたときのNode.jsアプリケーションのエントリポイントを設定します。これは、スナップショットビルドスクリプトで一度だけ呼び出すことができます。呼び出された場合、デシリアライズされたアプリケーションは起動するために追加のエントリスクリプトを必要とせず、単にコールバックとデシリアライズされたデータ(提供されている場合)を呼び出します。そうでない場合は、エントリスクリプトをデシリアライズされたアプリケーションに提供する必要があります。

v8.startupSnapshot.isBuildingSnapshot()#

Node.jsインスタンスがスナップショットをビルドするために実行されている場合、trueを返します。

クラス: v8.GCProfiler#

このAPIは、現在のスレッドでGCデータを収集します。

new v8.GCProfiler()#

v8.GCProfilerクラスの新しいインスタンスを作成します。

profiler.start()#

GCデータの収集を開始します。

profiler.stop()#

GCデータの収集を停止し、オブジェクトを返します。オブジェクトの内容は次のとおりです。

{
  "version": 1,
  "startTime": 1674059033862,
  "statistics": [
    {
      "gcType": "Scavenge",
      "beforeGC": {
        "heapStatistics": {
          "totalHeapSize": 5005312,
          "totalHeapSizeExecutable": 524288,
          "totalPhysicalSize": 5226496,
          "totalAvailableSize": 4341325216,
          "totalGlobalHandlesSize": 8192,
          "usedGlobalHandlesSize": 2112,
          "usedHeapSize": 4883840,
          "heapSizeLimit": 4345298944,
          "mallocedMemory": 254128,
          "externalMemory": 225138,
          "peakMallocedMemory": 181760
        },
        "heapSpaceStatistics": [
          {
            "spaceName": "read_only_space",
            "spaceSize": 0,
            "spaceUsedSize": 0,
            "spaceAvailableSize": 0,
            "physicalSpaceSize": 0
          }
        ]
      },
      "cost": 1574.14,
      "afterGC": {
        "heapStatistics": {
          "totalHeapSize": 6053888,
          "totalHeapSizeExecutable": 524288,
          "totalPhysicalSize": 5500928,
          "totalAvailableSize": 4341101384,
          "totalGlobalHandlesSize": 8192,
          "usedGlobalHandlesSize": 2112,
          "usedHeapSize": 4059096,
          "heapSizeLimit": 4345298944,
          "mallocedMemory": 254128,
          "externalMemory": 225138,
          "peakMallocedMemory": 181760
        },
        "heapSpaceStatistics": [
          {
            "spaceName": "read_only_space",
            "spaceSize": 0,
            "spaceUsedSize": 0,
            "spaceAvailableSize": 0,
            "physicalSpaceSize": 0
          }
        ]
      }
    }
  ],
  "endTime": 1674059036865
} 

例を次に示します。

const { GCProfiler } = require('v8');
const profiler = new GCProfiler();
profiler.start();
setTimeout(() => {
  console.log(profiler.stop());
}, 1000);