Spec-Zone.ru › Node.js 20 LTS

V8

Исходный код: lib/v8.js

Модуль node:v8 предоставляет API, специфичные для версии V8, встроенной в бинарник Node.js. К нему можно получить доступ следующим образом:

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

v8.cachedDataVersionTag()

Добавлена в: v8.0.0
  • Возвращает: <целое число>

Возвращает целое число, представляющее метку версии, полученную из версии V8, флагов командной строки и обнаруженных особенностей процессора. Это полезно для определения совместимости буфера 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 copy

v8.getHeapCodeStatistics()

Добавлена в: v12.8.0
  • Возвращает: <Объект>

Получает статистику о коде и его метаданных в куче, см. API V8 GetHeapCodeAndMetadataStatistics. Возвращает объект со следующими свойствами:

  • code_and_metadata_size <число>
  • bytecode_and_metadata_size <число>
  • external_script_source_size <число>
  • cpu_profiler_metadata_size <число>
{
  code_and_metadata_size: 212208,
  bytecode_and_metadata_size: 161368,
  external_script_source_size: 1410794,
  cpu_profiler_metadata_size: 0,
} copy

v8.getHeapSnapshot([options])

История
Версия Изменения
v19.1.0

Поддержка опций для настройки снимка кучи.

v11.13.0

Добавлена в: v11.13.0

  • options <Объект>

    • exposeInternals <логическое значение> Если истинно, отобразить внутренние данные в снимке кучи. По умолчанию: false.
    • exposeNumericValues <логическое значение> Если истинно, отобразить числовые значения в искусственных полях. По умолчанию: false.
  • Возвращает: <stream.Readable> Поток Readable, содержащий снимок кучи V8.

Создаёт снимок текущей кучи V8 и возвращает поток Readable, который может использоваться для чтения JSON-сериализованного представления. Этот формат JSON-потока предназначен для использования с инструментами, такими как Chrome DevTools. Схема JSON не документирована и специфична для движка V8. Поэтому схема может изменяться от одной версии V8 к другой.

Для создания снимка кучи требуется память примерно в два раза больше размера кучи в момент создания снимка. Это приводит к риску завершения процесса из-за ошибок OOM.

Создание снимка — это синхронная операция, которая блокирует цикл событий на время, зависящее от размера кучи.

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

v8.getHeapSpaceStatistics()

История
Версия Изменения
v7.5.0

Поддержка значений, превышающих диапазон 32-битных беззнаковых целых чисел.

v6.0.0

Добавлена в: v6.0.0

  • Возвращает: <Массив объектов>

Возвращает статистику о пространствах кучи V8, т.е. сегментах, составляющих кучу V8. Порядок пространств кучи и наличие пространства кучи не гарантируются, так как статистика предоставляется функцией V8 GetHeapSpaceStatistics и может меняться от одной версии V8 к другой.

Возвращаемое значение — массив объектов, содержащих следующие свойства:

  • space_name <строка>
  • space_size <число>
  • space_used_size <число>
  • space_available_size <число>
  • physical_space_size <число>
[
  {
    "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
  }
] copy

v8.getHeapStatistics()

История
Версия Изменения
v7.5.0

Поддержка значений, превышающих диапазон 32-битных беззнаковых целых чисел.

v7.2.0

Добавлены malloced_memory, peak_malloced_memory, и does_zap_garbage.

v1.0.0

Добавлена в: v1.0.0

  • Возвращает: <Объект>

Возвращает объект со следующими свойствами:

  • total_heap_size <число>
  • total_heap_size_executable <число>
  • total_physical_size <число>
  • total_available_size <число>
  • used_heap_size <число>
  • heap_size_limit <число>
  • malloced_memory <число>
  • peak_malloced_memory <число>
  • does_zap_garbage <число>
  • number_of_native_contexts <число>
  • number_of_detached_contexts <число>
  • total_global_handles_size <число>
  • used_global_handles_size <число>
  • external_memory <число>

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
} copy

v8.queryObjects(ctor[, options])

Добавлена в: v20.13.0
Стабильность: 1.1 - Активное развитие
  • ctor <Функция> Конструктор, который можно использовать для поиска по цепочке прототипов, чтобы отфильтровать целевые объекты в куче.
  • options <неопределено> | <Объект>
    • format <строка> Если это 'count', возвращается количество совпавших объектов. Если это 'summary', возвращается массив с краткими строковыми описаниями совпавших объектов.
  • Возвращает: {число|Массив<строка>}

Это аналогично queryObjects() API консоли, предоставляемой консолью Chromium DevTools. Его можно использовать для поиска объектов, имеющих соответствующий конструктор в цепочке прототипов в куче после полного сбора мусора, что может быть полезно для тестирования регрессии утечек памяти. Чтобы избежать неожиданных результатов, пользователи должны избегать использования этого API для конструкторов, реализацию которых они не контролируют, или для конструкторов, которые могут вызываться другими сторонами в приложении.

Чтобы избежать случайных утечек, этот API не возвращает сырые ссылки на найденные объекты. По умолчанию он возвращает количество найденных объектов. Если options.format является 'summary', он возвращает массив, содержащий краткие строковые представления каждого объекта. Предоставляемая в этом API видимость аналогична тому, что предоставляет дамп кучи, при этом пользователи могут сэкономить затраты на сериализацию и парсинг и напрямую фильтровать целевые объекты во время поиска.

В результатах включены только объекты, созданные в текущем контексте выполнения.

CJS модули

const { queryObjects } = require('node:v8');
class A { foo = 'bar'; }
console.log(queryObjects(A)); // 0
const a = new A();
console.log(queryObjects(A)); // 1
// [ "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));

class B extends A { bar = 'qux'; }
const b = new B();
console.log(queryObjects(B)); // 1
// [ "B { foo: 'bar', bar: 'qux' }" ]
console.log(queryObjects(B, { format: 'summary' }));

// Note that, when there are child classes inheriting from a constructor,
// the constructor also shows up in the prototype chain of the child
// classes's prototoype, so the child classes's prototoype would also be
// included in the result.
console.log(queryObjects(A));  // 3
// [ "B { foo: 'bar', bar: 'qux' }", 'A {}', "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));

MJS модули

import { queryObjects } from 'node:v8';
class A { foo = 'bar'; }
console.log(queryObjects(A)); // 0
const a = new A();
console.log(queryObjects(A)); // 1
// [ "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));

class B extends A { bar = 'qux'; }
const b = new B();
console.log(queryObjects(B)); // 1
// [ "B { foo: 'bar', bar: 'qux' }" ]
console.log(queryObjects(B, { format: 'summary' }));

// Note that, when there are child classes inheriting from a constructor,
// the constructor also shows up in the prototype chain of the child
// classes's prototoype, so the child classes's prototoype would also be
// included in the result.
console.log(queryObjects(A));  // 3
// [ "B { foo: 'bar', bar: 'qux' }", 'A {}', "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));

v8.setFlagsFromString(flags)

Добавлена в: v1.0.0
  • flags <строка>

Метод v8.setFlagsFromString() можно использовать для программированного задания флагов командной строки V8. Этот метод следует использовать с осторожностью. Изменение настроек после запуска виртуальной машины может привести к непредсказуемому поведению, включая сбои и потерю данных; или же он может просто ничего не сделать.

Доступные для версии 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); copy

v8.stopCoverage()

Добавлена в: v15.1.0, v14.18.0, v12.22.0

Метод v8.stopCoverage() позволяет пользователю остановить сбор данных покрытия, начатый NODE_V8_COVERAGE, чтобы V8 мог освободить записи счетчиков выполнения и оптимизировать код. Это можно использовать совместно с v8.takeCoverage(), если пользователь хочет собрать покрытие по требованию.

v8.takeCoverage()

Добавлена в: v15.1.0, v14.18.0, v12.22.0

Метод v8.takeCoverage() позволяет пользователю записать данные покрытия, начатые NODE_V8_COVERAGE, на диск по требованию. Этот метод можно вызывать несколько раз в течение жизненного цикла процесса. Каждый раз счетчик выполнения будет сброшен, а новый отчет о покрытии будет записан в каталог, указанный в NODE_V8_COVERAGE.

Когда процесс собирается завершиться, последний дамп покрытия по-прежнему будет записан на диск, если не будет вызван v8.stopCoverage() перед завершением процесса.

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

История
Версия Изменения
v19.1.0

Поддержка опций для настройки дампа кучи.

v18.0.0

Теперь будет брошено исключение, если файл не удалось записать.

v18.0.0

Согласовать коды ошибок по всем платформам.

v11.13.0

Добавлена в: v11.13.0

  • filename <строка> Путь к файлу, в который будет сохранён дамп кучи V8. Если не указано, будет сгенерировано имя файла по шаблону 'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot', где {pid} — PID процесса Node.js, а {thread_id} — 0, если writeHeapSnapshot() вызван из основного потока Node.js, или идентификатор потока-рабочего.
  • options <Объект>
    • exposeInternals <логическое значение> Если true, отобразить внутренние данные в дампе кучи. По умолчанию: false.
    • exposeNumericValues <логическое значение> Если true, отобразить числовые значения в искусственных полях. По умолчанию: false.
  • Возвращает: <строка> Имя файла, в который был сохранён дамп.

Генерирует дамп текущей кучи V8 и записывает его в JSON-файл. Этот файл предназначен для использования с такими инструментами, как Chrome DevTools. Схема JSON не документирована и специфична для движка V8, и может меняться от одной версии V8 к другой.

Дамп кучи относится к отдельному изоляту V8. При использовании потоков-работников дамп кучи, сгенерированный из основного потока, не будет содержать никакой информации о рабочих потоках, и наоборот.

Создание дампа кучи требует памяти примерно вдвое большей, чем размер кучи в момент создания дампа. Это влечёт риск завершения процесса из-за убийц из-за недостатка памяти.

Генерация дампа — это синхронная операция, которая блокирует цикл событий на время, зависящее от размера кучи.

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());
    }
  });
} copy

v8.setHeapSnapshotNearHeapLimit(limit)

Добавлена в: v18.10.0, v16.18.0
Стабильность: 1 - Экспериментальная
  • limit <целое число>

API является бесполезным действием, если --heapsnapshot-near-heap-limit уже задано из командной строки или API вызывается более одного раза. limit должно быть положительным целым числом. Подробнее см. --heapsnapshot-near-heap-limit.

API сериализации

API сериализации предоставляет средства для сериализации значений JavaScript таким образом, чтобы они были совместимы с алгоритмом структурированного клонирования HTML.

Формат обратно совместим (т.е. его безопасно хранить на диске). Равные значения JavaScript могут привести к различному сериализованному выводу.

v8.serialize(value)

Добавлен в: v8.0.0
  • value <любое>
  • Возвращает: <Буфер>

Использует DefaultSerializer для сериализации value в буфер.

ERR_BUFFER_TOO_LARGE будет брошен при попытке сериализовать большой объект, для которого требуется буфер больше, чем buffer.constants.MAX_LENGTH.

v8.deserialize(buffer)

Добавлен в: v8.0.0
  • buffer <Буфер> | <Массив типов> | <DataView> Буфер, возвращённый методом serialize().

Использует DefaultDeserializer с настройками по умолчанию для чтения значения JS из буфера.

Класс: v8.Serializer

Добавлен в: v8.0.0
new Serializer()

Создаёт новый объект Serializer.

serializer.writeHeader()

Записывает заголовок, который включает версию формата сериализации.

serializer.writeValue(value)
  • value <любое>

Сериализует значение JavaScript и добавляет сериализованное представление во внутренний буфер.

Бросает ошибку, если value не может быть сериализован.

serializer.releaseBuffer()
  • Возвращает: <Буфер>

Возвращает хранящийся внутренний буфер. Данный сериализатор не должен использоваться после освобождения буфера. Вызов этого метода приведёт к неопределённому поведению, если предыдущий запис был неудачным.

serializer.transferArrayBuffer(id, arrayBuffer)
  • id <целое без знака 32 бит> Целое без знака 32-бит.
  • arrayBuffer <ArrayBuffer> Экземпляр ArrayBuffer.

Помечает ArrayBuffer как содержащий содержимое, переданное вне очереди. Передайте соответствующий ArrayBuffer в контексте десериализации в deserializer.transferArrayBuffer().

serializer.writeUint32(value)
  • value <целое>

Записать целое без знака 32-бит. Для использования внутри пользовательского serializer._writeHostObject().

serializer.writeUint64(hi, lo)
  • hi <целое>
  • lo <целое>

Записать целое без знака 64-бит, разделённое на высокоразрядную и низкоразрядную части по 32 бита. Для использования внутри пользовательского serializer._writeHostObject().

serializer.writeDouble(value)
  • value <число>

Записать значение JS number. Для использования внутри пользовательского serializer._writeHostObject().

serializer.writeRawBytes(buffer)
  • buffer <Буфер> | <Массив типов> | <DataView>

Записать сырые байты во внутренний буфер сериализатора. Десериализатор потребует способ вычисления длины буфера. Для использования внутри пользовательского serializer._writeHostObject().

serializer._writeHostObject(object)
  • object <Объект>

Этот метод вызывается для записи какого-либо объекта хоста, т.е. объекта, созданного нативным связыванием C++. Если сериализация object невозможна, должна быть брошена соответствующая ошибка.

Этот метод отсутствует в классе Serializer сам по себе, но может быть предоставлен подклассами.

serializer._getDataCloneError(message)
  • message <строка>

Этот метод используется для создания объектов ошибок, которые будут брошены, когда объект не может быть клонирован.

По умолчанию этот метод использует конструктор Error, и может быть переопределен в подклассах.

serializer._getSharedArrayBufferId(sharedArrayBuffer)
  • sharedArrayBuffer <SharedArrayBuffer>

Этот метод вызывается, когда сериализатор собирается сериализовать объект SharedArrayBuffer. Он должен вернуть идентификатор объекта целым без знака 32-бит, используя тот же идентификатор, если этот SharedArrayBuffer уже был сериализован. При десериализации этот идентификатор будет передан в deserializer.transferArrayBuffer().

Если объект не может быть сериализован, должна быть брошена ошибка.

Этот метод отсутствует в классе Serializer сам по себе, но может быть предоставлен подклассами.

serializer._setTreatArrayBufferViewsAsHostObjects(flag)
  • flag <логическое значение> По умолчанию: false

Указывает, следует ли рассматривать объекты TypedArray и DataView как объекты хоста, т.е. передавать их в serializer._writeHostObject().

Класс: v8.Deserializer

Добавлен в: v8.0.0
new Deserializer(buffer)
  • buffer <Буфер> | <Массив типов> | <DataView> Буфер, возвращённый методом serializer.releaseBuffer().

Создаёт новый объект Deserializer.

deserializer.readHeader()

Читает и проверяет заголовок (включая версию формата). Может, например, отклонить неверный или неподдерживаемый формат данных. В этом случае будет брошена ошибка Error.

deserializer.readValue()

Десериализует значение JavaScript из буфера и возвращает его.

deserializer.transferArrayBuffer(id, arrayBuffer)
  • id <целое без знака 32 бит> Целое без знака 32-бит.
  • arrayBuffer <ArrayBuffer> | <SharedArrayBuffer> Экземпляр ArrayBuffer.

Помечает ArrayBuffer как содержащий содержимое, переданное вне очереди. Передайте соответствующий ArrayBuffer в контексте сериализации в serializer.transferArrayBuffer() (или верните id из serializer._getSharedArrayBufferId() в случае SharedArrayBuffer).

deserializer.getWireFormatVersion()
  • Возвращает: <целое>

Читает версию базового формата данных. Вероятно, будет полезна в основном для старого кода, читающего старые версии формата данных. Возможно, не будет вызвана до .readHeader().

deserializer.readUint32()
  • Возвращает: <целое>

Прочитать и вернуть целое без знака 32-бит. Для использования внутри пользовательского deserializer._readHostObject().

deserializer.readUint64()
  • Возвращает: <массив целых>

Прочитать и вернуть целое без знака 64-бит в виде массива [hi, lo] с двумя элементами по 32-бит. Для использования внутри пользовательского deserializer._readHostObject().

deserializer.readDouble()
  • Возвращает: <число>

Прочитать значение JS number. Для использования внутри пользовательского deserializer._readHostObject().

deserializer.readRawBytes(length)
END_OF_DOCUMENT_MARKER
  • length <integer>
  • Возвращает: <Buffer>

Считывает сырые байты из внутреннего буфера десериализатора. Параметр length должен соответствовать длине буфера, переданного в serializer.writeRawBytes(). Для использования внутри пользовательского deserializer._readHostObject().

deserializer._readHostObject()

Этот метод используется для чтения какого-либо объекта хоста, т.е. объекта, созданного нативным C++-связыванием. Если данные невозможно десериализовать, необходимо выбросить соответствующее исключение.

Этот метод отсутствует в классе Deserializer сам по себе, но может быть предоставлен подклассами.

Класс: v8.DefaultSerializer

Добавлена в: v8.0.0

Подкласс Serializer, который сериализует TypedArray (в частности, Buffer) и DataView объекты как объекты хоста и хранит только часть их базовых ArrayBuffer.

Класс: v8.DefaultDeserializer

Добавлена в: v8.0.0

Подкласс Deserializer, соответствующий формату, записанному DefaultSerializer.

Обработчики событий обещаний

Интерфейс promiseHooks может использоваться для отслеживания событий жизненного цикла обещания. Чтобы отслеживать все асинхронные операции, см. async_hooks, который использует этот модуль для создания событий жизненного цикла обещаний в дополнение к событиям для других асинхронных ресурсов. Для управления контекстом запроса см. 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(); copy

promiseHooks.onInit(init)

Добавлена в: v17.1.0, v16.14.0
  • init <Функция> Обработчик вызова init при создании обещания.
  • Возвращает: <Функция> Вызов для остановки обработчика.

Обработчик init должен быть обычной функцией. Передача асинхронной функции вызовет ошибку, так как она приведет к бесконечному циклу микрозадач.

MJS-модули

import { promiseHooks } from 'node:v8';

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

CJS-модули

const { promiseHooks } = require('node:v8');

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

promiseHooks.onSettled(settled)

Добавлена в: v17.1.0, v16.14.0
  • settled <Функция> Обработчик вызова settled при разрешении или отклонении обещания.
  • Возвращает: <Функция> Вызов для остановки обработчика.

Обработчик settled должен быть обычной функцией. Передача асинхронной функции вызовет ошибку, так как она приведет к бесконечному циклу микрозадач.

MJS-модули

import { promiseHooks } from 'node:v8';

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

CJS-модули

const { promiseHooks } = require('node:v8');

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

promiseHooks.onBefore(before)

Добавлена в: v17.1.0, v16.14.0
  • before <Функция> Обработчик вызова before перед выполнением продолжения обещания.
  • Возвращает: <Функция> Вызов для остановки обработчика.

Обработчик before должен быть обычной функцией. Передача асинхронной функции вызовет ошибку, так как она приведет к бесконечному циклу микрозадач.

MJS-модули

import { promiseHooks } from 'node:v8';

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

CJS-модули

const { promiseHooks } = require('node:v8');

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

promiseHooks.onAfter(after)

Добавлена в: v17.1.0, v16.14.0
  • after <Функция> Обработчик вызова after после выполнения продолжения обещания.
  • Возвращает: <Функция> Вызов для остановки обработчика.

Обработчик after должен быть обычной функцией. Передача асинхронной функции вызовет ошибку, так как она приведет к бесконечному циклу микрозадач.

MJS-модули

import { promiseHooks } from 'node:v8';

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

CJS-модули

const { promiseHooks } = require('node:v8');

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

promiseHooks.createHook(callbacks)

Добавлена в: v17.1.0, v16.14.0
  • callbacks <Объект> Обработчики вызовов Обработчики вызовов для регистрации
    • init <Функция> Обработчик вызова init.
    • before <Функция> Обработчик вызова before.
    • after <Функция> Обработчик вызова after.
    • settled <Функция> Обработчик вызова settled.
  • Возвращает: <Функция> Используется для отключения обработчиков

Обработчики вызовов должны быть обычными функциями. Передача асинхронных функций вызовет ошибку, так как она приведет к бесконечному циклу микрозадач.

Регистрирует функции, которые будут вызываться для различных событий жизненного цикла каждого обещания.

Обработчики init()/before()/after()/settled() вызываются для соответствующих событий в течение жизненного цикла обещания.

Все обработчики необязательны. Например, если нужно отслеживать только создание обещания, то необходимо передать только обработчик init. Подробности всех функций, которые можно передать в callbacks, указаны в разделе Обработчики вызовов.

MJS-модули

import { promiseHooks } from 'node:v8';

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

CJS-модули

const { promiseHooks } = require('node:v8');

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

Обработчики вызовов

Ключевые события в жизненном цикле обещания сгруппированы в четыре области: создание обещания, перед/после вызова обработчика продолжения или вокруг await, а также при разрешении или отклонении обещания.

Хотя эти обработчики похожи на обработчики async_hooks, у них нет обработчика destroy. Другие типы асинхронных ресурсов, как правило, представляют собой сокеты или дескрипторы файлов, которые имеют четкое состояние «закрыто» для выражения события жизненного цикла destroy, в то время как обещания остаются пригодными для использования до тех пор, пока код может их достичь. Отслеживание сборки мусора используется для адаптации обещаний к модели событий async_hooks, однако это отслеживание очень дорогостоящее, и они могут не быть собраны мусором.

Поскольку обещания являются асинхронными ресурсами, жизненный цикл которых отслеживается с помощью механизма обработчиков обещаний, обработчики init(), before(), after(), и settled() не должны быть асинхронными функциями, так как они создают больше обещаний, что приведет к бесконечному циклу.

Хотя этот API используется для подачи событий обещаний в async_hooks, порядок между ними не определен. Оба API многопользовательские и поэтому могут генерировать события в любом порядке относительно друг друга.

init(promise, parent)
  • promise <Обещание> Создаваемое обещание.
  • parent <Обещание> Обещание, продолжаемое, если применимо.

Вызывается при создании обещания. Это не означает, что соответствующие события before/after произойдут, только что такая возможность существует. Это произойдет, если обещание создано, но никогда не получит продолжение.

before(promise)
  • promise <Обещание>

Вызывается перед выполнением продолжения обещания. Это может быть в виде then(), catch(), или finally() обработчиков или возобновления await.

Обработчик before будет вызываться от 0 до N раз. Обработчик before обычно вызывается 0 раз, если для обещания никогда не было продолжения. Обработчик before может вызываться многократно в случае, когда от одного и того же обещания было сделано много продолжений.

after(promise)
  • promise <Обещание>

Вызывается сразу после выполнения продолжения обещания. Это может быть после then(), catch(), или finally() обработчика или перед await после другого await.

settled(promise)
  • promise <Обещание>

Вызывается, когда обещание получает значение разрешения или отклонения. Это может произойти синхронно в случае Promise.resolve() или Promise.reject().

Модуль снимков состояния запуска

Добавлен в: v18.6.0, v16.17.0
Уровень стабильности: 1 - Экспериментальный

Интерфейс v8.startupSnapshot может быть использован для добавления обработчиков сериализации и десериализации пользовательских снимков состояния запуска.

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

В примере выше, 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); copy

Результат выполнения будет выводить данные, десериализованные из снимка во время запуска, используя обновлённые 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. copy

В настоящее время приложение, десериализованное из снимка пользовательского уровня, не может быть снова заснято в виде снимка, поэтому эти API доступны только для приложений, которые не десериализованы из снимка пользовательского уровня.

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

Добавлен в: v18.6.0, v16.17.0
  • callback <Функция> Обработчик, вызываемый перед сериализацией.
  • data <любой> Дополнительные данные, которые будут переданы обработчику callback при вызове.

Добавляет обработчик, который вызывается, когда экземпляр Node.js собирается сериализоваться в снимок и завершить работу. Это может быть использовано для освобождения ресурсов, которые не должны или не могут быть сериализованы, или для преобразования пользовательских данных в форму, более подходящую для сериализации.

Обработчики выполняются в порядке их добавления.

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

Добавлен в: v18.6.0, v16.17.0
  • callback <Функция> Обработчик, вызываемый после десериализации снимка.
  • data <любой> Дополнительные данные, которые будут переданы обработчику callback при вызове.

Добавляет обработчик, который вызывается, когда экземпляр Node.js десериализован из снимка. callback и data (если указаны) будут сериализованы в снимок, они могут быть использованы для повторной инициализации состояния приложения или для повторного получения ресурсов, необходимых приложении при перезапуске из снимка.

Обработчики выполняются в порядке их добавления.

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

Добавлен в: v18.6.0, v16.17.0
  • callback <Функция> Обработчик, вызываемый в качестве точки входа после десериализации снимка.
  • data <любой> Дополнительные данные, которые будут переданы обработчику callback при вызове.

Устанавливает точку входа приложения Node.js при десериализации из снимка. Может быть вызван только один раз в скрипте создания снимка. Если вызван, десериализованное приложение больше не нуждается в дополнительном скрипте входа для запуска и просто вызовет обработчик вместе с десериализованными данными (если предоставлены), в противном случае скрипт точки входа всё ещё должен быть предоставлен десериализованному приложению.

v8.startupSnapshot.isBuildingSnapshot()

Добавлен в: v18.6.0, v16.17.0
  • Возвращает: <логическое значение>

Возвращает true, если экземпляр Node.js запущен для построения снимка.

Класс: v8.GCProfiler

Добавлен в: v19.6.0, v18.15.0

Этот API собирает данные GC в текущей нити.

new v8.GCProfiler()

Добавлен в: v19.6.0, v18.15.0

Создаёт новый экземпляр класса v8.GCProfiler.

profiler.start()

Добавлен в: v19.6.0, v18.15.0

Начинает сбор данных GC.

profiler.stop()

Добавлен в: v19.6.0, v18.15.0

Останавливает сбор данных 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
} copy

Вот пример.

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

© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v20.x/docs/api/v8.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API