| # V8 |
| |
| <!--introduced_in=v4.0.0--> |
| |
| The `v8` module exposes APIs that are specific to the version of [V8][] |
| built into the Node.js binary. It can be accessed using: |
| |
| ```js |
| const v8 = require('v8'); |
| ``` |
| |
| The APIs and implementation are subject to change at any time. |
| |
| ## `v8.cachedDataVersionTag()` |
| <!-- YAML |
| added: v8.0.0 |
| --> |
| |
| * Returns: {integer} |
| |
| Returns an integer representing a "version tag" derived from the V8 version, |
| command line flags and detected CPU features. This is useful for determining |
| whether a [`vm.Script`][] `cachedData` buffer is compatible with this instance |
| of V8. |
| |
| ## `v8.getHeapSpaceStatistics()` |
| <!-- YAML |
| added: v6.0.0 |
| changes: |
| - version: v7.5.0 |
| pr-url: https://github.com/nodejs/node/pull/10186 |
| description: Support values exceeding the 32-bit unsigned integer range. |
| --> |
| |
| * Returns: {Object[]} |
| |
| Returns statistics about the V8 heap spaces, i.e. the segments which make up |
| the V8 heap. Neither the ordering of heap spaces, nor the availability of a |
| heap space can be guaranteed as the statistics are provided via the V8 |
| [`GetHeapSpaceStatistics`][] function and may change from one V8 version to the |
| next. |
| |
| The value returned is an array of objects containing the following properties: |
| |
| * `space_name` {string} |
| * `space_size` {number} |
| * `space_used_size` {number} |
| * `space_available_size` {number} |
| * `physical_space_size` {number} |
| |
| ```json |
| [ |
| { |
| "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.getHeapSnapshot()` |
| <!-- YAML |
| added: v11.13.0 |
| --> |
| |
| * Returns: {stream.Readable} A Readable Stream containing the V8 heap snapshot |
| |
| Generates a snapshot of the current V8 heap and returns a Readable |
| Stream that may be used to read the JSON serialized representation. |
| This JSON stream format is intended to be used with tools such as |
| Chrome DevTools. The JSON schema is undocumented and specific to the |
| V8 engine, and may change from one version of V8 to the next. |
| |
| ```js |
| const stream = v8.getHeapSnapshot(); |
| stream.pipe(process.stdout); |
| ``` |
| |
| ## `v8.getHeapStatistics()` |
| <!-- YAML |
| added: v1.0.0 |
| changes: |
| - version: v7.2.0 |
| pr-url: https://github.com/nodejs/node/pull/8610 |
| description: Added `malloced_memory`, `peak_malloced_memory`, |
| and `does_zap_garbage`. |
| - version: v7.5.0 |
| pr-url: https://github.com/nodejs/node/pull/10186 |
| description: Support values exceeding the 32-bit unsigned integer range. |
| --> |
| |
| * Returns: {Object} |
| |
| Returns an object with the following properties: |
| |
| * `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} |
| |
| `does_zap_garbage` is a 0/1 boolean, which signifies whether the |
| `--zap_code_space` option is enabled or not. This makes V8 overwrite heap |
| garbage with a bit pattern. The RSS footprint (resident memory set) gets bigger |
| because it continuously touches all heap pages and that makes them less likely |
| to get swapped out by the operating system. |
| |
| `number_of_native_contexts` The value of native_context is the number of the |
| top-level contexts currently active. Increase of this number over time indicates |
| a memory leak. |
| |
| `number_of_detached_contexts` The value of detached_context is the number |
| of contexts that were detached and not yet garbage collected. This number |
| being non-zero indicates a potential memory leak. |
| |
| <!-- eslint-skip --> |
| ```js |
| { |
| 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 |
| } |
| ``` |
| |
| ## `v8.getHeapCodeStatistics()` |
| <!-- YAML |
| added: v12.8.0 |
| --> |
| |
| * Returns: {Object} |
| |
| Returns an object with the following properties: |
| |
| * `code_and_metadata_size` {number} |
| * `bytecode_and_metadata_size` {number} |
| * `external_script_source_size` {number} |
| |
| <!-- eslint-skip --> |
| ```js |
| { |
| code_and_metadata_size: 212208, |
| bytecode_and_metadata_size: 161368, |
| external_script_source_size: 1410794 |
| } |
| ``` |
| |
| ## `v8.setFlagsFromString(flags)` |
| <!-- YAML |
| added: v1.0.0 |
| --> |
| |
| * `flags` {string} |
| |
| The `v8.setFlagsFromString()` method can be used to programmatically set |
| V8 command line flags. This method should be used with care. Changing settings |
| after the VM has started may result in unpredictable behavior, including |
| crashes and data loss; or it may simply do nothing. |
| |
| The V8 options available for a version of Node.js may be determined by running |
| `node --v8-options`. |
| |
| Usage: |
| |
| ```js |
| // Print GC events to stdout for one minute. |
| const v8 = require('v8'); |
| v8.setFlagsFromString('--trace_gc'); |
| setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3); |
| ``` |
| |
| ## `v8.writeHeapSnapshot([filename])` |
| <!-- YAML |
| added: v11.13.0 |
| --> |
| |
| * `filename` {string} The file path where the V8 heap snapshot is to be |
| saved. If not specified, a file name with the pattern |
| `'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot'` will be |
| generated, where `{pid}` will be the PID of the Node.js process, |
| `{thread_id}` will be `0` when `writeHeapSnapshot()` is called from |
| the main Node.js thread or the id of a worker thread. |
| * Returns: {string} The filename where the snapshot was saved. |
| |
| Generates a snapshot of the current V8 heap and writes it to a JSON |
| file. This file is intended to be used with tools such as Chrome |
| DevTools. The JSON schema is undocumented and specific to the V8 |
| engine, and may change from one version of V8 to the next. |
| |
| A heap snapshot is specific to a single V8 isolate. When using |
| [Worker Threads][], a heap snapshot generated from the main thread will |
| not contain any information about the workers, and vice versa. |
| |
| ```js |
| const { writeHeapSnapshot } = require('v8'); |
| const { |
| Worker, |
| isMainThread, |
| parentPort |
| } = require('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()); |
| } |
| }); |
| } |
| ``` |
| |
| ## Serialization API |
| |
| The serialization API provides means of serializing JavaScript values in a way |
| that is compatible with the [HTML structured clone algorithm][]. |
| |
| The format is backward-compatible (i.e. safe to store to disk). |
| Equal JavaScript values may result in different serialized output. |
| |
| ### `v8.serialize(value)` |
| <!-- YAML |
| added: v8.0.0 |
| --> |
| |
| * `value` {any} |
| * Returns: {Buffer} |
| |
| Uses a [`DefaultSerializer`][] to serialize `value` into a buffer. |
| |
| ### `v8.deserialize(buffer)` |
| <!-- YAML |
| added: v8.0.0 |
| --> |
| |
| * `buffer` {Buffer|TypedArray|DataView} A buffer returned by [`serialize()`][]. |
| |
| Uses a [`DefaultDeserializer`][] with default options to read a JS value |
| from a buffer. |
| |
| ### Class: `v8.Serializer` |
| <!-- YAML |
| added: v8.0.0 |
| --> |
| |
| #### `new Serializer()` |
| Creates a new `Serializer` object. |
| |
| #### `serializer.writeHeader()` |
| |
| Writes out a header, which includes the serialization format version. |
| |
| #### `serializer.writeValue(value)` |
| |
| * `value` {any} |
| |
| Serializes a JavaScript value and adds the serialized representation to the |
| internal buffer. |
| |
| This throws an error if `value` cannot be serialized. |
| |
| #### `serializer.releaseBuffer()` |
| |
| * Returns: {Buffer} |
| |
| Returns the stored internal buffer. This serializer should not be used once |
| the buffer is released. Calling this method results in undefined behavior |
| if a previous write has failed. |
| |
| #### `serializer.transferArrayBuffer(id, arrayBuffer)` |
| |
| * `id` {integer} A 32-bit unsigned integer. |
| * `arrayBuffer` {ArrayBuffer} An `ArrayBuffer` instance. |
| |
| Marks an `ArrayBuffer` as having its contents transferred out of band. |
| Pass the corresponding `ArrayBuffer` in the deserializing context to |
| [`deserializer.transferArrayBuffer()`][]. |
| |
| #### `serializer.writeUint32(value)` |
| |
| * `value` {integer} |
| |
| Write a raw 32-bit unsigned integer. |
| For use inside of a custom [`serializer._writeHostObject()`][]. |
| |
| #### `serializer.writeUint64(hi, lo)` |
| |
| * `hi` {integer} |
| * `lo` {integer} |
| |
| Write a raw 64-bit unsigned integer, split into high and low 32-bit parts. |
| For use inside of a custom [`serializer._writeHostObject()`][]. |
| |
| #### `serializer.writeDouble(value)` |
| |
| * `value` {number} |
| |
| Write a JS `number` value. |
| For use inside of a custom [`serializer._writeHostObject()`][]. |
| |
| #### `serializer.writeRawBytes(buffer)` |
| |
| * `buffer` {Buffer|TypedArray|DataView} |
| |
| Write raw bytes into the serializer’s internal buffer. The deserializer |
| will require a way to compute the length of the buffer. |
| For use inside of a custom [`serializer._writeHostObject()`][]. |
| |
| #### `serializer._writeHostObject(object)` |
| |
| * `object` {Object} |
| |
| This method is called to write some kind of host object, i.e. an object created |
| by native C++ bindings. If it is not possible to serialize `object`, a suitable |
| exception should be thrown. |
| |
| This method is not present on the `Serializer` class itself but can be provided |
| by subclasses. |
| |
| #### `serializer._getDataCloneError(message)` |
| |
| * `message` {string} |
| |
| This method is called to generate error objects that will be thrown when an |
| object can not be cloned. |
| |
| This method defaults to the [`Error`][] constructor and can be overridden on |
| subclasses. |
| |
| #### `serializer._getSharedArrayBufferId(sharedArrayBuffer)` |
| |
| * `sharedArrayBuffer` {SharedArrayBuffer} |
| |
| This method is called when the serializer is going to serialize a |
| `SharedArrayBuffer` object. It must return an unsigned 32-bit integer ID for |
| the object, using the same ID if this `SharedArrayBuffer` has already been |
| serialized. When deserializing, this ID will be passed to |
| [`deserializer.transferArrayBuffer()`][]. |
| |
| If the object cannot be serialized, an exception should be thrown. |
| |
| This method is not present on the `Serializer` class itself but can be provided |
| by subclasses. |
| |
| #### `serializer._setTreatArrayBufferViewsAsHostObjects(flag)` |
| |
| * `flag` {boolean} **Default:** `false` |
| |
| Indicate whether to treat `TypedArray` and `DataView` objects as |
| host objects, i.e. pass them to [`serializer._writeHostObject()`][]. |
| |
| ### Class: `v8.Deserializer` |
| <!-- YAML |
| added: v8.0.0 |
| --> |
| |
| #### `new Deserializer(buffer)` |
| |
| * `buffer` {Buffer|TypedArray|DataView} A buffer returned by |
| [`serializer.releaseBuffer()`][]. |
| |
| Creates a new `Deserializer` object. |
| |
| #### `deserializer.readHeader()` |
| |
| Reads and validates a header (including the format version). |
| May, for example, reject an invalid or unsupported wire format. In that case, |
| an `Error` is thrown. |
| |
| #### `deserializer.readValue()` |
| |
| Deserializes a JavaScript value from the buffer and returns it. |
| |
| #### `deserializer.transferArrayBuffer(id, arrayBuffer)` |
| |
| * `id` {integer} A 32-bit unsigned integer. |
| * `arrayBuffer` {ArrayBuffer|SharedArrayBuffer} An `ArrayBuffer` instance. |
| |
| Marks an `ArrayBuffer` as having its contents transferred out of band. |
| Pass the corresponding `ArrayBuffer` in the serializing context to |
| [`serializer.transferArrayBuffer()`][] (or return the `id` from |
| [`serializer._getSharedArrayBufferId()`][] in the case of `SharedArrayBuffer`s). |
| |
| #### `deserializer.getWireFormatVersion()` |
| |
| * Returns: {integer} |
| |
| Reads the underlying wire format version. Likely mostly to be useful to |
| legacy code reading old wire format versions. May not be called before |
| `.readHeader()`. |
| |
| #### `deserializer.readUint32()` |
| |
| * Returns: {integer} |
| |
| Read a raw 32-bit unsigned integer and return it. |
| For use inside of a custom [`deserializer._readHostObject()`][]. |
| |
| #### `deserializer.readUint64()` |
| |
| * Returns: {integer[]} |
| |
| Read a raw 64-bit unsigned integer and return it as an array `[hi, lo]` |
| with two 32-bit unsigned integer entries. |
| For use inside of a custom [`deserializer._readHostObject()`][]. |
| |
| #### `deserializer.readDouble()` |
| |
| * Returns: {number} |
| |
| Read a JS `number` value. |
| For use inside of a custom [`deserializer._readHostObject()`][]. |
| |
| #### `deserializer.readRawBytes(length)` |
| |
| * `length` {integer} |
| * Returns: {Buffer} |
| |
| Read raw bytes from the deserializer’s internal buffer. The `length` parameter |
| must correspond to the length of the buffer that was passed to |
| [`serializer.writeRawBytes()`][]. |
| For use inside of a custom [`deserializer._readHostObject()`][]. |
| |
| #### `deserializer._readHostObject()` |
| |
| This method is called to read some kind of host object, i.e. an object that is |
| created by native C++ bindings. If it is not possible to deserialize the data, |
| a suitable exception should be thrown. |
| |
| This method is not present on the `Deserializer` class itself but can be |
| provided by subclasses. |
| |
| ### Class: `v8.DefaultSerializer` |
| <!-- YAML |
| added: v8.0.0 |
| --> |
| |
| A subclass of [`Serializer`][] that serializes `TypedArray` |
| (in particular [`Buffer`][]) and `DataView` objects as host objects, and only |
| stores the part of their underlying `ArrayBuffer`s that they are referring to. |
| |
| ### Class: `v8.DefaultDeserializer` |
| <!-- YAML |
| added: v8.0.0 |
| --> |
| |
| A subclass of [`Deserializer`][] corresponding to the format written by |
| [`DefaultSerializer`][]. |
| |
| [`Buffer`]: buffer.html |
| [`DefaultDeserializer`]: #v8_class_v8_defaultdeserializer |
| [`DefaultSerializer`]: #v8_class_v8_defaultserializer |
| [`Deserializer`]: #v8_class_v8_deserializer |
| [`Error`]: errors.html#errors_class_error |
| [`GetHeapSpaceStatistics`]: https://v8docs.nodesource.com/node-13.2/d5/dda/classv8_1_1_isolate.html#ac673576f24fdc7a33378f8f57e1d13a4 |
| [`Serializer`]: #v8_class_v8_serializer |
| [`deserializer._readHostObject()`]: #v8_deserializer_readhostobject |
| [`deserializer.transferArrayBuffer()`]: #v8_deserializer_transferarraybuffer_id_arraybuffer |
| [`serialize()`]: #v8_v8_serialize_value |
| [`serializer._getSharedArrayBufferId()`]: #v8_serializer_getsharedarraybufferid_sharedarraybuffer |
| [`serializer._writeHostObject()`]: #v8_serializer_writehostobject_object |
| [`serializer.releaseBuffer()`]: #v8_serializer_releasebuffer |
| [`serializer.transferArrayBuffer()`]: #v8_serializer_transferarraybuffer_id_arraybuffer |
| [`serializer.writeRawBytes()`]: #v8_serializer_writerawbytes_buffer |
| [`vm.Script`]: vm.html#vm_constructor_new_vm_script_code_options |
| [HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm |
| [V8]: https://developers.google.com/v8/ |
| [Worker Threads]: worker_threads.html |