1# V8 2 3<!--introduced_in=v4.0.0--> 4 5<!-- source_link=lib/v8.js --> 6 7The `v8` module exposes APIs that are specific to the version of [V8][] 8built into the Node.js binary. It can be accessed using: 9 10```js 11const v8 = require('v8'); 12``` 13 14## `v8.cachedDataVersionTag()` 15<!-- YAML 16added: v8.0.0 17--> 18 19* Returns: {integer} 20 21Returns an integer representing a version tag derived from the V8 version, 22command-line flags, and detected CPU features. This is useful for determining 23whether a [`vm.Script`][] `cachedData` buffer is compatible with this instance 24of V8. 25 26```js 27console.log(v8.cachedDataVersionTag()); // 3947234607 28// The value returned by v8.cachedDataVersionTag() is derived from the V8 29// version, command-line flags, and detected CPU features. Test that the value 30// does indeed update when flags are toggled. 31v8.setFlagsFromString('--allow_natives_syntax'); 32console.log(v8.cachedDataVersionTag()); // 183726201 33``` 34 35## `v8.getHeapCodeStatistics()` 36<!-- YAML 37added: v12.8.0 38--> 39 40* Returns: {Object} 41 42Returns an object with the following properties: 43 44* `code_and_metadata_size` {number} 45* `bytecode_and_metadata_size` {number} 46* `external_script_source_size` {number} 47 48<!-- eslint-skip --> 49```js 50{ 51 code_and_metadata_size: 212208, 52 bytecode_and_metadata_size: 161368, 53 external_script_source_size: 1410794 54} 55``` 56 57## `v8.getHeapSnapshot()` 58<!-- YAML 59added: v11.13.0 60--> 61 62* Returns: {stream.Readable} A Readable Stream containing the V8 heap snapshot 63 64Generates a snapshot of the current V8 heap and returns a Readable 65Stream that may be used to read the JSON serialized representation. 66This JSON stream format is intended to be used with tools such as 67Chrome DevTools. The JSON schema is undocumented and specific to the 68V8 engine. Therefore, the schema may change from one version of V8 to the next. 69 70```js 71// Print heap snapshot to the console 72const v8 = require('v8'); 73const stream = v8.getHeapSnapshot(); 74stream.pipe(process.stdout); 75``` 76 77## `v8.getHeapSpaceStatistics()` 78<!-- YAML 79added: v6.0.0 80changes: 81 - version: v7.5.0 82 pr-url: https://github.com/nodejs/node/pull/10186 83 description: Support values exceeding the 32-bit unsigned integer range. 84--> 85 86* Returns: {Object[]} 87 88Returns statistics about the V8 heap spaces, i.e. the segments which make up 89the V8 heap. Neither the ordering of heap spaces, nor the availability of a 90heap space can be guaranteed as the statistics are provided via the V8 91[`GetHeapSpaceStatistics`][] function and may change from one V8 version to the 92next. 93 94The value returned is an array of objects containing the following properties: 95 96* `space_name` {string} 97* `space_size` {number} 98* `space_used_size` {number} 99* `space_available_size` {number} 100* `physical_space_size` {number} 101 102```json 103[ 104 { 105 "space_name": "new_space", 106 "space_size": 2063872, 107 "space_used_size": 951112, 108 "space_available_size": 80824, 109 "physical_space_size": 2063872 110 }, 111 { 112 "space_name": "old_space", 113 "space_size": 3090560, 114 "space_used_size": 2493792, 115 "space_available_size": 0, 116 "physical_space_size": 3090560 117 }, 118 { 119 "space_name": "code_space", 120 "space_size": 1260160, 121 "space_used_size": 644256, 122 "space_available_size": 960, 123 "physical_space_size": 1260160 124 }, 125 { 126 "space_name": "map_space", 127 "space_size": 1094160, 128 "space_used_size": 201608, 129 "space_available_size": 0, 130 "physical_space_size": 1094160 131 }, 132 { 133 "space_name": "large_object_space", 134 "space_size": 0, 135 "space_used_size": 0, 136 "space_available_size": 1490980608, 137 "physical_space_size": 0 138 } 139] 140``` 141 142## `v8.getHeapStatistics()` 143<!-- YAML 144added: v1.0.0 145changes: 146 - version: v7.5.0 147 pr-url: https://github.com/nodejs/node/pull/10186 148 description: Support values exceeding the 32-bit unsigned integer range. 149 - version: v7.2.0 150 pr-url: https://github.com/nodejs/node/pull/8610 151 description: Added `malloced_memory`, `peak_malloced_memory`, 152 and `does_zap_garbage`. 153--> 154 155* Returns: {Object} 156 157Returns an object with the following properties: 158 159* `total_heap_size` {number} 160* `total_heap_size_executable` {number} 161* `total_physical_size` {number} 162* `total_available_size` {number} 163* `used_heap_size` {number} 164* `heap_size_limit` {number} 165* `malloced_memory` {number} 166* `peak_malloced_memory` {number} 167* `does_zap_garbage` {number} 168* `number_of_native_contexts` {number} 169* `number_of_detached_contexts` {number} 170 171`does_zap_garbage` is a 0/1 boolean, which signifies whether the 172`--zap_code_space` option is enabled or not. This makes V8 overwrite heap 173garbage with a bit pattern. The RSS footprint (resident set size) gets bigger 174because it continuously touches all heap pages and that makes them less likely 175to get swapped out by the operating system. 176 177`number_of_native_contexts` The value of native_context is the number of the 178top-level contexts currently active. Increase of this number over time indicates 179a memory leak. 180 181`number_of_detached_contexts` The value of detached_context is the number 182of contexts that were detached and not yet garbage collected. This number 183being non-zero indicates a potential memory leak. 184 185<!-- eslint-skip --> 186```js 187{ 188 total_heap_size: 7326976, 189 total_heap_size_executable: 4194304, 190 total_physical_size: 7326976, 191 total_available_size: 1152656, 192 used_heap_size: 3476208, 193 heap_size_limit: 1535115264, 194 malloced_memory: 16384, 195 peak_malloced_memory: 1127496, 196 does_zap_garbage: 0, 197 number_of_native_contexts: 1, 198 number_of_detached_contexts: 0 199} 200``` 201 202## `v8.setFlagsFromString(flags)` 203<!-- YAML 204added: v1.0.0 205--> 206 207* `flags` {string} 208 209The `v8.setFlagsFromString()` method can be used to programmatically set 210V8 command-line flags. This method should be used with care. Changing settings 211after the VM has started may result in unpredictable behavior, including 212crashes and data loss; or it may simply do nothing. 213 214The V8 options available for a version of Node.js may be determined by running 215`node --v8-options`. 216 217Usage: 218 219```js 220// Print GC events to stdout for one minute. 221const v8 = require('v8'); 222v8.setFlagsFromString('--trace_gc'); 223setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3); 224``` 225 226## `v8.stopCoverage()` 227 228<!-- YAML 229added: v14.18.0 230--> 231 232The `v8.stopCoverage()` method allows the user to stop the coverage collection 233started by [`NODE_V8_COVERAGE`][], so that V8 can release the execution count 234records and optimize code. This can be used in conjunction with 235[`v8.takeCoverage()`][] if the user wants to collect the coverage on demand. 236 237## `v8.takeCoverage()` 238 239<!-- YAML 240added: v14.18.0 241--> 242 243The `v8.takeCoverage()` method allows the user to write the coverage started by 244[`NODE_V8_COVERAGE`][] to disk on demand. This method can be invoked multiple 245times during the lifetime of the process. Each time the execution counter will 246be reset and a new coverage report will be written to the directory specified 247by [`NODE_V8_COVERAGE`][]. 248 249When the process is about to exit, one last coverage will still be written to 250disk unless [`v8.stopCoverage()`][] is invoked before the process exits. 251 252## `v8.writeHeapSnapshot([filename])` 253<!-- YAML 254added: v11.13.0 255--> 256 257* `filename` {string} The file path where the V8 heap snapshot is to be 258 saved. If not specified, a file name with the pattern 259 `'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot'` will be 260 generated, where `{pid}` will be the PID of the Node.js process, 261 `{thread_id}` will be `0` when `writeHeapSnapshot()` is called from 262 the main Node.js thread or the id of a worker thread. 263* Returns: {string} The filename where the snapshot was saved. 264 265Generates a snapshot of the current V8 heap and writes it to a JSON 266file. This file is intended to be used with tools such as Chrome 267DevTools. The JSON schema is undocumented and specific to the V8 268engine, and may change from one version of V8 to the next. 269 270A heap snapshot is specific to a single V8 isolate. When using 271[worker threads][], a heap snapshot generated from the main thread will 272not contain any information about the workers, and vice versa. 273 274```js 275const { writeHeapSnapshot } = require('v8'); 276const { 277 Worker, 278 isMainThread, 279 parentPort 280} = require('worker_threads'); 281 282if (isMainThread) { 283 const worker = new Worker(__filename); 284 285 worker.once('message', (filename) => { 286 console.log(`worker heapdump: ${filename}`); 287 // Now get a heapdump for the main thread. 288 console.log(`main thread heapdump: ${writeHeapSnapshot()}`); 289 }); 290 291 // Tell the worker to create a heapdump. 292 worker.postMessage('heapdump'); 293} else { 294 parentPort.once('message', (message) => { 295 if (message === 'heapdump') { 296 // Generate a heapdump for the worker 297 // and return the filename to the parent. 298 parentPort.postMessage(writeHeapSnapshot()); 299 } 300 }); 301} 302``` 303 304## Serialization API 305 306The serialization API provides means of serializing JavaScript values in a way 307that is compatible with the [HTML structured clone algorithm][]. 308 309The format is backward-compatible (i.e. safe to store to disk). 310Equal JavaScript values may result in different serialized output. 311 312### `v8.serialize(value)` 313<!-- YAML 314added: v8.0.0 315--> 316 317* `value` {any} 318* Returns: {Buffer} 319 320Uses a [`DefaultSerializer`][] to serialize `value` into a buffer. 321 322### `v8.deserialize(buffer)` 323<!-- YAML 324added: v8.0.0 325--> 326 327* `buffer` {Buffer|TypedArray|DataView} A buffer returned by [`serialize()`][]. 328 329Uses a [`DefaultDeserializer`][] with default options to read a JS value 330from a buffer. 331 332### Class: `v8.Serializer` 333<!-- YAML 334added: v8.0.0 335--> 336 337#### `new Serializer()` 338Creates a new `Serializer` object. 339 340#### `serializer.writeHeader()` 341 342Writes out a header, which includes the serialization format version. 343 344#### `serializer.writeValue(value)` 345 346* `value` {any} 347 348Serializes a JavaScript value and adds the serialized representation to the 349internal buffer. 350 351This throws an error if `value` cannot be serialized. 352 353#### `serializer.releaseBuffer()` 354 355* Returns: {Buffer} 356 357Returns the stored internal buffer. This serializer should not be used once 358the buffer is released. Calling this method results in undefined behavior 359if a previous write has failed. 360 361#### `serializer.transferArrayBuffer(id, arrayBuffer)` 362 363* `id` {integer} A 32-bit unsigned integer. 364* `arrayBuffer` {ArrayBuffer} An `ArrayBuffer` instance. 365 366Marks an `ArrayBuffer` as having its contents transferred out of band. 367Pass the corresponding `ArrayBuffer` in the deserializing context to 368[`deserializer.transferArrayBuffer()`][]. 369 370#### `serializer.writeUint32(value)` 371 372* `value` {integer} 373 374Write a raw 32-bit unsigned integer. 375For use inside of a custom [`serializer._writeHostObject()`][]. 376 377#### `serializer.writeUint64(hi, lo)` 378 379* `hi` {integer} 380* `lo` {integer} 381 382Write a raw 64-bit unsigned integer, split into high and low 32-bit parts. 383For use inside of a custom [`serializer._writeHostObject()`][]. 384 385#### `serializer.writeDouble(value)` 386 387* `value` {number} 388 389Write a JS `number` value. 390For use inside of a custom [`serializer._writeHostObject()`][]. 391 392#### `serializer.writeRawBytes(buffer)` 393 394* `buffer` {Buffer|TypedArray|DataView} 395 396Write raw bytes into the serializer’s internal buffer. The deserializer 397will require a way to compute the length of the buffer. 398For use inside of a custom [`serializer._writeHostObject()`][]. 399 400#### `serializer._writeHostObject(object)` 401 402* `object` {Object} 403 404This method is called to write some kind of host object, i.e. an object created 405by native C++ bindings. If it is not possible to serialize `object`, a suitable 406exception should be thrown. 407 408This method is not present on the `Serializer` class itself but can be provided 409by subclasses. 410 411#### `serializer._getDataCloneError(message)` 412 413* `message` {string} 414 415This method is called to generate error objects that will be thrown when an 416object can not be cloned. 417 418This method defaults to the [`Error`][] constructor and can be overridden on 419subclasses. 420 421#### `serializer._getSharedArrayBufferId(sharedArrayBuffer)` 422 423* `sharedArrayBuffer` {SharedArrayBuffer} 424 425This method is called when the serializer is going to serialize a 426`SharedArrayBuffer` object. It must return an unsigned 32-bit integer ID for 427the object, using the same ID if this `SharedArrayBuffer` has already been 428serialized. When deserializing, this ID will be passed to 429[`deserializer.transferArrayBuffer()`][]. 430 431If the object cannot be serialized, an exception should be thrown. 432 433This method is not present on the `Serializer` class itself but can be provided 434by subclasses. 435 436#### `serializer._setTreatArrayBufferViewsAsHostObjects(flag)` 437 438* `flag` {boolean} **Default:** `false` 439 440Indicate whether to treat `TypedArray` and `DataView` objects as 441host objects, i.e. pass them to [`serializer._writeHostObject()`][]. 442 443### Class: `v8.Deserializer` 444<!-- YAML 445added: v8.0.0 446--> 447 448#### `new Deserializer(buffer)` 449 450* `buffer` {Buffer|TypedArray|DataView} A buffer returned by 451 [`serializer.releaseBuffer()`][]. 452 453Creates a new `Deserializer` object. 454 455#### `deserializer.readHeader()` 456 457Reads and validates a header (including the format version). 458May, for example, reject an invalid or unsupported wire format. In that case, 459an `Error` is thrown. 460 461#### `deserializer.readValue()` 462 463Deserializes a JavaScript value from the buffer and returns it. 464 465#### `deserializer.transferArrayBuffer(id, arrayBuffer)` 466 467* `id` {integer} A 32-bit unsigned integer. 468* `arrayBuffer` {ArrayBuffer|SharedArrayBuffer} An `ArrayBuffer` instance. 469 470Marks an `ArrayBuffer` as having its contents transferred out of band. 471Pass the corresponding `ArrayBuffer` in the serializing context to 472[`serializer.transferArrayBuffer()`][] (or return the `id` from 473[`serializer._getSharedArrayBufferId()`][] in the case of `SharedArrayBuffer`s). 474 475#### `deserializer.getWireFormatVersion()` 476 477* Returns: {integer} 478 479Reads the underlying wire format version. Likely mostly to be useful to 480legacy code reading old wire format versions. May not be called before 481`.readHeader()`. 482 483#### `deserializer.readUint32()` 484 485* Returns: {integer} 486 487Read a raw 32-bit unsigned integer and return it. 488For use inside of a custom [`deserializer._readHostObject()`][]. 489 490#### `deserializer.readUint64()` 491 492* Returns: {integer[]} 493 494Read a raw 64-bit unsigned integer and return it as an array `[hi, lo]` 495with two 32-bit unsigned integer entries. 496For use inside of a custom [`deserializer._readHostObject()`][]. 497 498#### `deserializer.readDouble()` 499 500* Returns: {number} 501 502Read a JS `number` value. 503For use inside of a custom [`deserializer._readHostObject()`][]. 504 505#### `deserializer.readRawBytes(length)` 506 507* `length` {integer} 508* Returns: {Buffer} 509 510Read raw bytes from the deserializer’s internal buffer. The `length` parameter 511must correspond to the length of the buffer that was passed to 512[`serializer.writeRawBytes()`][]. 513For use inside of a custom [`deserializer._readHostObject()`][]. 514 515#### `deserializer._readHostObject()` 516 517This method is called to read some kind of host object, i.e. an object that is 518created by native C++ bindings. If it is not possible to deserialize the data, 519a suitable exception should be thrown. 520 521This method is not present on the `Deserializer` class itself but can be 522provided by subclasses. 523 524### Class: `v8.DefaultSerializer` 525<!-- YAML 526added: v8.0.0 527--> 528 529A subclass of [`Serializer`][] that serializes `TypedArray` 530(in particular [`Buffer`][]) and `DataView` objects as host objects, and only 531stores the part of their underlying `ArrayBuffer`s that they are referring to. 532 533### Class: `v8.DefaultDeserializer` 534<!-- YAML 535added: v8.0.0 536--> 537 538A subclass of [`Deserializer`][] corresponding to the format written by 539[`DefaultSerializer`][]. 540 541[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm 542[V8]: https://developers.google.com/v8/ 543[`Buffer`]: buffer.md 544[`DefaultDeserializer`]: #v8_class_v8_defaultdeserializer 545[`DefaultSerializer`]: #v8_class_v8_defaultserializer 546[`Deserializer`]: #v8_class_v8_deserializer 547[`Error`]: errors.md#errors_class_error 548[`GetHeapSpaceStatistics`]: https://v8docs.nodesource.com/node-13.2/d5/dda/classv8_1_1_isolate.html#ac673576f24fdc7a33378f8f57e1d13a4 549[`NODE_V8_COVERAGE`]: cli.md#cli_node_v8_coverage_dir 550[`Serializer`]: #v8_class_v8_serializer 551[`deserializer._readHostObject()`]: #v8_deserializer_readhostobject 552[`deserializer.transferArrayBuffer()`]: #v8_deserializer_transferarraybuffer_id_arraybuffer 553[`serialize()`]: #v8_v8_serialize_value 554[`serializer._getSharedArrayBufferId()`]: #v8_serializer_getsharedarraybufferid_sharedarraybuffer 555[`serializer._writeHostObject()`]: #v8_serializer_writehostobject_object 556[`serializer.releaseBuffer()`]: #v8_serializer_releasebuffer 557[`serializer.transferArrayBuffer()`]: #v8_serializer_transferarraybuffer_id_arraybuffer 558[`serializer.writeRawBytes()`]: #v8_serializer_writerawbytes_buffer 559[`v8.stopCoverage()`]: #v8_v8_stopcoverage 560[`v8.takeCoverage()`]: #v8_v8_takecoverage 561[`vm.Script`]: vm.md#vm_new_vm_script_code_options 562[worker threads]: worker_threads.md 563