Node.js v21.7.2 ドキュメント
- Node.js v21.7.2
-
► 目次
- V8
v8.cachedDataVersionTag()
v8.getHeapCodeStatistics()
v8.getHeapSnapshot([options])
v8.getHeapSpaceStatistics()
v8.getHeapStatistics()
v8.setFlagsFromString(flags)
v8.stopCoverage()
v8.takeCoverage()
v8.writeHeapSnapshot([filename[,options]])
v8.setHeapSnapshotNearHeapLimit(limit)
- シリアライゼーション API
v8.serialize(value)
v8.deserialize(buffer)
- クラス:
v8.Serializer
new Serializer()
serializer.writeHeader()
serializer.writeValue(value)
serializer.releaseBuffer()
serializer.transferArrayBuffer(id, arrayBuffer)
serializer.writeUint32(value)
serializer.writeUint64(hi, lo)
serializer.writeDouble(value)
serializer.writeRawBytes(buffer)
serializer._writeHostObject(object)
serializer._getDataCloneError(message)
serializer._getSharedArrayBufferId(sharedArrayBuffer)
serializer._setTreatArrayBufferViewsAsHostObjects(flag)
- クラス:
v8.Deserializer
new Deserializer(buffer)
deserializer.readHeader()
deserializer.readValue()
deserializer.transferArrayBuffer(id, arrayBuffer)
deserializer.getWireFormatVersion()
deserializer.readUint32()
deserializer.readUint64()
deserializer.readDouble()
deserializer.readRawBytes(length)
deserializer._readHostObject()
- クラス:
v8.DefaultSerializer
- クラス:
v8.DefaultDeserializer
- Promise フック
- スタートアップスナップショット API
- クラス:
v8.GCProfiler
- V8
-
► インデックス
- アサーションテスト
- 非同期コンテキスト追跡
- 非同期フック
- バッファ
- C++ アドオン
- Node-API を使用した C/C++ アドオン
- C++ エンベダー API
- 子プロセス
- クラスタ
- コマンドラインオプション
- コンソール
- Corepack
- 暗号
- デバッガ
- 非推奨 API
- 診断チャネル
- DNS
- ドメイン
- エラー
- イベント
- ファイルシステム
- グローバル
- HTTP
- HTTP/2
- HTTPS
- インスペクタ
- 国際化
- モジュール: CommonJS モジュール
- モジュール: ECMAScript モジュール
- モジュール:
node:module
API - モジュール: パッケージ
- Net
- OS
- パス
- パフォーマンスフック
- パーミッション
- プロセス
- Punycode
- クエリ文字列
- Readline
- REPL
- レポート
- 単一実行ファイルアプリケーション
- ストリーム
- 文字列デコーダー
- テストランナー
- タイマー
- TLS/SSL
- トレースイベント
- TTY
- UDP/データグラム
- URL
- ユーティリティ
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- ワーカースレッド
- Zlib
- ► 他のバージョン
- ► オプション
V8#
ソースコード: lib/v8.js
node:v8
モジュールは、Node.js バイナリに組み込まれた V8 のバージョンに固有の API を公開します。アクセスするには、次を使用します。
const v8 = require('node:v8');
v8.cachedDataVersionTag()
#
- 戻り値: <integer>
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()
#
- 戻り値: <Object>
ヒープ内のコードとそのメタデータに関する統計情報を取得します。V8 の GetHeapCodeAndMetadataStatistics
API を参照してください。次のプロパティを持つオブジェクトを返します。
code_and_metadata_size
<number>bytecode_and_metadata_size
<number>external_script_source_size
<number>cpu_profiler_metadata_size
<number>
{
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> -
戻り値: <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()
#
- 戻り値: <Object[]>
V8 ヒープスペース、つまり V8 ヒープを構成するセグメントに関する統計情報を返します。ヒープスペースの順序も、ヒープスペースの可用性も保証されません。統計情報は V8 の GetHeapSpaceStatistics
関数によって提供され、V8 のバージョンによって変更される可能性があります。
返される値は、次のプロパティを含むオブジェクトの配列です。
space_name
<string>space_size
<number>space_used_size
<number>space_available_size
<number>physical_space_size
<number>
[
{
"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()
#
- 戻り値: <Object>
次のプロパティを持つオブジェクトを返します。
total_heap_size
<number>total_heap_size_executable
<number>total_physical_size
<number>total_available_size
<number>used_heap_size
<number>heap_size_limit
<number>malloced_memory
<number>peak_malloced_memory
<number>does_zap_garbage
<number>number_of_native_contexts
<number>number_of_detached_contexts
<number>total_global_handles_size
<number>used_global_handles_size
<number>external_memory
<number>
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)
#
flags
<string>
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>- 戻り値: <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)
#
limit
<integer>
--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)
#
buffer
<Buffer> | <TypedArray> | <DataView>serialize()
によって返されたバッファ。
デフォルトオプションのDefaultDeserializer
を使用して、バッファからJS値を読み取ります。
クラス: v8.Serializer
#
new Serializer()
#
新しいSerializer
オブジェクトを作成します。
serializer.writeHeader()
#
シリアライゼーションフォーマットバージョンを含むヘッダーを書き込みます。
serializer.writeValue(value)
#
value
<any>
JavaScript値をシリアライズし、シリアライズされた表現を内部バッファに追加します。
value
をシリアライズできない場合、これはエラーをスローします。
serializer.releaseBuffer()
#
- 戻り値: <Buffer>
格納されている内部バッファを返します。バッファが解放されたら、このシリアライザーを使用しないでください。前回の書き込みに失敗した場合、このメソッドを呼び出すと未定義の動作が発生します。
serializer.transferArrayBuffer(id, arrayBuffer)
#
id
<integer> 32ビット符号なし整数。arrayBuffer
<ArrayBuffer>ArrayBuffer
インスタンス。
ArrayBuffer
の内容が帯域外に転送されたことをマークします。対応するArrayBuffer
を逆シリアル化コンテキストでdeserializer.transferArrayBuffer()
に渡します。
serializer.writeUint32(value)
#
value
<integer>
生の32ビット符号なし整数を書き込みます。カスタムのserializer._writeHostObject()
内で使用します。
serializer.writeUint64(hi, lo)
#
高位と低位の32ビット部分に分割された生の64ビット符号なし整数を書き込みます。カスタムのserializer._writeHostObject()
内で使用します。
serializer.writeDouble(value)
#
value
<number>
JSのnumber
値を書き込みます。カスタムのserializer._writeHostObject()
内で使用します。
serializer.writeRawBytes(buffer)
#
buffer
<Buffer> | <TypedArray> | <DataView>
シリアライザーの内部バッファに生のバイトを書き込みます。デシリアライザーは、バッファの長さを計算する方法が必要です。カスタムのserializer._writeHostObject()
内で使用します。
serializer._writeHostObject(object)
#
object
<Object>
このメソッドは、ネイティブC ++バインディングによって作成されたオブジェクトなど、ある種のホストオブジェクトを書き込むために呼び出されます。 object
をシリアライズできない場合は、適切な例外をスローする必要があります。
このメソッドは、Serializer
クラス自体には存在しませんが、サブクラスによって提供できます。
serializer._getDataCloneError(message)
#
message
<string>
このメソッドは、オブジェクトを複製できないときにスローされるエラーオブジェクトを生成するために呼び出されます。
このメソッドはデフォルトでError
コンストラクターに設定されており、サブクラスでオーバーライドできます。
serializer._getSharedArrayBufferId(sharedArrayBuffer)
#
sharedArrayBuffer
<SharedArrayBuffer>
このメソッドは、シリアライザがSharedArrayBuffer
オブジェクトをシリアル化しようとする際に呼び出されます。このメソッドは、オブジェクトに対して符号なし32ビット整数IDを返さなければなりません。このSharedArrayBuffer
が既にシリアル化されている場合は、同じIDを使用します。デシリアライズするとき、このIDはdeserializer.transferArrayBuffer()
に渡されます。
オブジェクトをシリアル化できない場合は、例外をスローする必要があります。
このメソッドは、Serializer
クラス自体には存在しませんが、サブクラスによって提供できます。
serializer._setTreatArrayBufferViewsAsHostObjects(flag)
#
flag
<boolean> デフォルト値:false
TypedArray
およびDataView
オブジェクトをホストオブジェクトとして扱うかどうか、つまりserializer._writeHostObject()
に渡すかどうかを指定します。
クラス: v8.Deserializer
#
new Deserializer(buffer)
#
buffer
<Buffer> | <TypedArray> | <DataView>serializer.releaseBuffer()
によって返されるバッファ。
新しいDeserializer
オブジェクトを作成します。
deserializer.readHeader()
#
ヘッダー(フォーマットバージョンを含む)を読み取って検証します。例えば、無効またはサポートされていないワイヤフォーマットを拒否する場合があります。その場合、Error
がスローされます。
deserializer.readValue()
#
バッファからJavaScriptの値をデシリアライズして返します。
deserializer.transferArrayBuffer(id, arrayBuffer)
#
id
<integer> 32ビット符号なし整数。arrayBuffer
<ArrayBuffer> | <SharedArrayBuffer>ArrayBuffer
インスタンス。
ArrayBuffer
の内容が帯域外に転送されたことをマークします。対応するArrayBuffer
をシリアル化コンテキストでserializer.transferArrayBuffer()
に渡します(または、SharedArrayBuffer
の場合、serializer._getSharedArrayBufferId()
からid
を返します)。
deserializer.getWireFormatVersion()
#
- 戻り値: <integer>
基盤となるワイヤフォーマットバージョンを読み取ります。おそらく、古いワイヤフォーマットバージョンを読み取るレガシーコードに役立ちます。 .readHeader()
の前に呼び出すことはできません。
deserializer.readUint32()
#
- 戻り値: <integer>
生の32ビット符号なし整数を読み取って返します。カスタムdeserializer._readHostObject()
内で使用します。
deserializer.readUint64()
#
- 戻り値: <integer[]>
生の64ビット符号なし整数を読み取り、2つの32ビット符号なし整数エントリを持つ配列[hi, lo]
として返します。カスタムdeserializer._readHostObject()
内で使用します。
deserializer.readDouble()
#
- 戻り値: <number>
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
<Function> Promiseが作成されたときに呼び出すinit
コールバック。- 戻り値: <Function> フックを停止するための呼び出し。
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
<Function> Promiseが解決または拒否されたときに呼び出すsettled
コールバック。- 戻り値: <Function> フックを停止するための呼び出し。
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
<Function> Promiseの継続ハンドラが実行される前に呼び出すbefore
コールバック。- 戻り値: <Function> フックを停止するための呼び出し。
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
<Function> Promiseの継続ハンドラが実行された後に呼び出すafter
コールバック。- 戻り値: <Function> フックを停止するための呼び出し。
after
フックはプレーン関数でなければなりません。非同期関数を指定すると、無限のマイクロタスクループが生成されるため、スローされます。
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onAfter((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onAfter((promise) => {});
promiseHooks.createHook(callbacks)
#
callbacks
<Object> 登録するフックコールバックinit
<Function>init
コールバック。before
<Function>before
コールバック。after
<Function>after
コールバック。settled
<Function>settled
コールバック。
- 戻り値: <Function> フックを無効にするために使用されます
フックコールバックはプレーン関数でなければなりません。非同期関数を指定すると、無限のマイクロタスクループが生成されるため、スローされます。
各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が構築されたときに呼び出されます。これは、対応するbefore
/after
イベントが発生することを意味するのではなく、可能性が存在することを意味します。これは、継続を取得することなくPromiseが作成された場合に発生します。
before(promise)
#
promise
<Promise>
Promiseの継続が実行される前に呼び出されます。これは、then()
、catch()
、またはfinally()
ハンドラー、あるいは再開するawait
の形式をとることができます。
before
コールバックは0からN回呼び出されます。Promiseに対して継続が行われなかった場合、before
コールバックは通常0回呼び出されます。同じPromiseから多くの継続が行われた場合、before
コールバックは何度も呼び出される可能性があります。
after(promise)
#
promise
<Promise>
Promiseの継続が実行された直後に呼び出されます。これは、then()
、catch()
、またはfinally()
ハンドラーの後、あるいは別のawait
の後のawait
の前になる場合があります。
settled(promise)
#
promise
<Promise>
Promiseが解決または拒否値を受け取ったときに呼び出されます。これは、Promise.resolve()
またはPromise.reject()
の場合、同期的に発生する可能性があります。
スタートアップスナップショットAPI#
v8.startupSnapshot
インターフェースは、カスタムスタートアップスナップショットのシリアライズおよびデシリアライズフックを追加するために使用できます。
$ node --snapshot-blob snapshot.blob --build-snapshot entry.js
# This launches a process with the snapshot
$ node --snapshot-blob snapshot.blob
上記の例では、entry.js
はv8.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.env
とprocess.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インスタンスがスナップショットからデシリアライズされたときに呼び出されるコールバックを追加します。 callback
とdata
(提供されている場合)はスナップショットにシリアライズされ、アプリケーションの状態を再初期化したり、スナップショットからアプリケーションが再起動されたときにアプリケーションが必要とするリソースを再取得したりするために使用できます。
コールバックは、追加された順序で実行されます。
v8.startupSnapshot.setDeserializeMainFunction(callback[, data])
#
callback
<Function> スナップショットのデシリアライズ後、エントリポイントとして呼び出されるコールバック。data
<any> コールバックが呼び出されたときにコールバックに渡されるオプションデータ。
これは、スナップショットからデシリアライズされたときのNode.jsアプリケーションのエントリポイントを設定します。これは、スナップショットビルドスクリプトで一度だけ呼び出すことができます。呼び出された場合、デシリアライズされたアプリケーションは起動するために追加のエントリスクリプトを必要とせず、単にコールバックとデシリアライズされたデータ(提供されている場合)を呼び出します。そうでない場合は、エントリスクリプトをデシリアライズされたアプリケーションに提供する必要があります。
v8.startupSnapshot.isBuildingSnapshot()
#
- 戻り値: <boolean>
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);