V8¶
Модуль node:v8
предоставляет API, специфичные для версии V8, встроенной в двоичный код Node.js. Доступ к нему можно получить, используя:
1 |
|
v8.cachedDataVersionTag()
¶
- Возвращает:
<integer>
Возвращает целое число, представляющее тег версии, полученный из версии V8, флагов командной строки и обнаруженных особенностей CPU. Это полезно для определения совместимости буфера vm.Script
cachedData
с данным экземпляром V8.
1 2 3 4 5 6 |
|
v8.getHeapCodeStatistics()
¶
- Возвращает:
<Object>
Получение статистики о коде и его метаданных в куче, см. API V8 GetHeapCodeAndMetadataStatistics
. Возвращает объект со следующими свойствами:
code_and_metadata_size
<number>
bytecode_and_metadata_size
<number>
external_script_source_size
<number>
cpu_profiler_metadata_size
<number>
1 2 3 4 5 6 |
|
v8.getHeapSnapshot([options])
¶
options
<Object>
- Возвращает:
<stream.Readable>
Readable, содержащий снимок кучи V8.
Генерирует снимок текущей кучи V8 и возвращает поток Readable, который можно использовать для чтения сериализованного представления JSON. Этот формат потока JSON предназначен для использования с такими инструментами, как Chrome DevTools. Схема JSON недокументирована и специфична для движка V8. Поэтому схема может меняться от одной версии V8 к другой.
Для создания моментального снимка кучи требуется память, примерно вдвое превышающая размер кучи на момент создания моментального снимка. Это приводит к риску того, что OOM killers завершит процесс.
Создание моментального снимка - это синхронная операция, которая блокирует цикл событий на время, зависящее от размера кучи.
1 2 3 4 |
|
v8.getHeapSpaceStatistics()
¶
- Возвращает: {Объект[]}
Возвращает статистику о пространствах кучи V8, т.е. сегментах, составляющих кучу V8. Ни порядок пространств кучи, ни доступность пространства кучи не могут быть гарантированы, поскольку статистика предоставляется через функцию V8 GetHeapSpaceStatistics
и может меняться от версии V8 к версии.
Возвращаемое значение представляет собой массив объектов, содержащих следующие свойства:
space_name
<string>
space_size
<number>
space_used_size
<number>
space_available_size
<number>
физический_размер_пространства
<number>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
v8.getHeapStatistics()
¶
- Возвращает:
<Object>
Возвращает объект со следующими свойствами:
total_heap_size
<number>
total_heap_size_executable
<number>
total_physical_size
<number>
total_available_size
<number>
используемый размер кучи
<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>
использованный_размер_глобальных_ручек
<number>
внешняя_память
<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 - это размер памяти для буферов массивов и внешних строк.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
v8.setFlagsFromString(flags)
¶
flags
<string>
Метод v8.setFlagsFromString()
может быть использован для программной установки флагов командной строки V8. Этот метод следует использовать с осторожностью. Изменение настроек после запуска виртуальной машины может привести к непредсказуемому поведению, включая сбои и потерю данных; или же он может просто ничего не сделать.
Опции V8, доступные для версии Node.js, можно определить, выполнив команду node --v8-options
.
Использование:
1 2 3 4 5 6 |
|
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}
будет PID процесса Node.js,{thread_id}
будет0
, еслиwriteHeapSnapshot()
вызывается из главного потока Node.js или id рабочего потока.options
<Object>
- Возвращает:
<string>
Имя файла, в котором был сохранен снимок.
Генерирует снимок текущей кучи V8 и записывает его в файл JSON. Этот файл предназначен для использования с такими инструментами, как Chrome DevTools. Схема JSON недокументирована и специфична для движка V8, и может меняться от версии V8 к версии.
Снимок кучи специфичен для одного изолятора V8. При использовании рабочих потоков, heap snapshot, созданный из главного потока, не будет содержать никакой информации о рабочих потоках, и наоборот.
Для создания снимка кучи требуется память, примерно вдвое превышающая размер кучи на момент создания снимка. Это приводит к риску того, что OOM killers завершит процесс.
Создание моментального снимка - это синхронная операция, которая блокирует цикл событий на время, зависящее от размера кучи.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
v8.setHeapSnapshotNearHeapLimit(limit)
¶
Стабильность: 1 – Экспериментальная
Экспериментальная
limit
<integer>
API не работает, если --heapsnapshot-near-heap-limit
уже установлен из командной строки или API вызывается более одного раза. limit
должно быть положительным целым числом. Дополнительную информацию смотрите в --heapsnapshot-near-heap-limit
.
API сериализации¶
API сериализации предоставляет средства для сериализации значений JavaScript способом, совместимым с HTML structured clone algorithm.
Формат является обратно совместимым (т.е. безопасным для хранения на диске). Одинаковые значения JavaScript могут приводить к разным сериализованным выводам.
v8.serialize(value)
¶
Использует DefaultSerializer
для сериализации значения
в буфер.
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 и добавляет сериализованное представление во внутренний буфер.
Если значение
не может быть сериализовано, возникает ошибка.
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)
¶
Запись необработанного 64-битного беззнакового целого числа, разделенного на старшую и младшую 32-битные части. Для использования внутри пользовательского serializer._writeHostObject()
.
serializer.writeDouble(value)
¶
значение
<number>
Запись значения JS числа
. Для использования внутри пользовательского 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 для объекта, используя тот же ID, если этот SharedArrayBuffer
уже был сериализован. При десериализации этот ID будет передан в deserializer.transferArrayBuffer()
.
Если объект не может быть сериализован, должно быть выброшено исключение.
Этот метод отсутствует в самом классе Serializer
, но может быть предоставлен подклассами.
serializer._setTreatArrayBufferViewsAsHostObjects(flag)
¶
flag
<boolean>
По умолчанию:false
.
Укажите, следует ли рассматривать объекты TypedArray
и DataView
как хост-объекты, т.е. передавать их в serializer._writeHostObject()
.
Класс: v8.Deserializer
¶
новый десериализатор(буфер)
¶
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()
(или возвращает id
из serializer._getSharedArrayBufferId()
в случае SharedArrayBuffer
).
deserializer.getWireFormatVersion()
¶
- Возвращает:
<integer>
Читает базовую версию формата проводов. Вероятно, будет полезен в основном для устаревшего кода, читающего старые версии формата проводов. Не может быть вызван до .readHeader()
.
deserializer.readUint32()
¶
- Возвращает:
<integer>
.
Читает необработанное 32-битное беззнаковое целое число и возвращает его. Для использования внутри пользовательского deserializer._readHostObject()
.
deserializer.readUint64()
¶
- Возвращает: {integer[]}
Читает необработанное 64-битное беззнаковое целое число и возвращает его в виде массива [hi, lo]
с двумя 32-битными беззнаковыми целыми. Для использования внутри пользовательского deserializer._readHostObject()
.
deserializer.readDouble()
¶
- Возвращает:
<number>
Считывает значение JS число
. Для использования внутри пользовательского 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
.
Крючки обещания¶
Интерфейс promiseHooks
можно использовать для отслеживания событий жизненного цикла обещания. Для отслеживания всех асинхронных действий смотрите async_hooks
, который внутренне использует этот модуль для создания событий жизненного цикла обещания в дополнение к событиям для других асинхронных ресурсов. Для управления контекстом запроса смотрите AsyncLocalStorage
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
promiseHooks.onInit(init)
¶
init
<Function>
Обратный вызовinit
для вызова при создании обещания.- Возвращает:
<Function>
Вызов для остановки хука.
Хук init
должен быть простой функцией. Предоставление асинхронной функции приведет к ошибке, так как создаст бесконечный цикл микрозадачи.
1 2 3 |
|
1 2 3 |
|
promiseHooks.onSettled(settled)
¶
settled
<Function>
Обратный вызовsettled
callback для вызова, когда обещание разрешено или отклонено.- Возвращает:
<Function>
Вызов для остановки хука.
Хук settled
должен быть простой функцией. Если предоставить асинхронную функцию, то произойдет отказ, так как это приведет к бесконечному циклу микрозадачи.
1 2 3 |
|
1 2 3 |
|
promiseHooks.onBefore(before)
¶
before
<Function>
Обратный вызовbefore
callback для вызова перед выполнением продолжения обещания.- Возвращает:
<Function>
Вызов для остановки хука.
Хук before
должен быть простой функцией. Предоставление асинхронной функции приведет к ошибке, так как создаст бесконечный цикл микрозадачи.
1 2 3 |
|
1 2 3 |
|
promiseHooks.onAfter(after)
¶
after
<Function>
Обратный вызовafter
callback для вызова после выполнения продолжения обещания.- Возвращает:
<Function>
Вызов для остановки хука.
Хук after
должен быть простой функцией. Предоставление асинхронной функции приведет к ошибке, так как создаст бесконечный цикл микрозадачи.
1 2 3 |
|
1 2 3 |
|
promiseHooks.createHook(callbacks)
¶
callbacks
<Object>
Обратные вызовы крюка для регистрацииinit
<Function>
Обратный вызовinit
.before
<Function>
Обратный вызовbefore
.after
<Function>
Обратный вызовafter
.settled
<Function>
Обратный вызовsettled
callback.
- Возвращает:
<Function>
Используется для отключения хуков.
Обратные вызовы хуков должны быть обычными функциями. Предоставление асинхронных функций приведет к отбрасыванию, так как создаст бесконечный цикл микрозадачи.
Регистрирует функции, которые будут вызываться для различных событий времени жизни каждого обещания.
Обратные вызовы init()
/ before()
/ after()
/ settled()
вызываются для соответствующих событий во время жизни обещания.
Все обратные вызовы необязательны. Например, если необходимо отслеживать только создание обещания, то нужно передать только обратный вызов init
. Специфика всех функций, которые могут быть переданы в callbacks
, находится в разделе Hook Callbacks.
1 2 3 4 5 |
|
1 2 3 4 5 |
|
Обратные вызовы крючков¶
Ключевые события во время жизни обещания были разделены на четыре области: создание обещания, до/после вызова обработчика продолжения или вокруг await, а также когда обещание разрешается или отклоняется.
Хотя эти крючки похожи на крючки из async_hooks
, в них отсутствует крючок destroy
. Другие типы async-ресурсов обычно представляют собой сокеты или дескрипторы файлов, которые имеют отдельное состояние "закрыто" для выражения события жизненного цикла destroy
, в то время как обещания остаются пригодными для использования до тех пор, пока код может обращаться к ним. Чтобы обещания вписывались в модель событий async_hooks
, используется отслеживание сборки мусора, однако это отслеживание очень дорого, и, возможно, они даже не всегда будут собираться.
Поскольку обещания являются асинхронными ресурсами, жизненный цикл которых отслеживается с помощью механизма promise hooks, обратные вызовы init()
, before()
, after()
и settled()
не должны быть асинхронными функциями, поскольку они создают больше обещаний, что приведет к бесконечному циклу.
Хотя этот API используется для передачи событий обещаний в async_hooks
, порядок между ними не определен. Оба API являются многопользовательскими и поэтому могут создавать события в любом порядке относительно друг друга.
init(promise, parent)
¶
promise
<Promise>
Создаваемое обещание.parent
<Promise>
Обещание, от которого оно продолжается, если применимо.
Вызывается при создании обещания. Это не означает, что произойдут соответствующие события "до" и "после", только то, что такая возможность существует. Это произойдет, если обещание будет создано без получения продолжения.
before(promise)
¶
promise
<Promise>
Вызывается перед выполнением продолжения обещания. Это может быть в виде обработчиков then()
, catch()
, finally()
или возобновления await
.
Обратный вызов before
будет вызван от 0 до N раз. Обычно обратный вызов before
вызывается 0 раз, если для обещания не было сделано никакого продолжения. Обратный вызов before
может быть вызван много раз в случае, если было сделано много продолжений от одного и того же обещания.
after(promise)
¶
promise
<Promise>
Вызывается сразу после выполнения продолжения обещания. Это может быть после обработчика then()
, catch()
или finally()
или перед await
после другого await
.
settled(promise)
¶
promise
<Promise>
Вызывается, когда обещание получает значение разрешения или отклонения. Это может произойти синхронно в случае Promise.resolve()
или Promise.reject()
.
Startup Snapshot API¶
Стабильность: 1 – Экспериментальная
Экспериментальный
Интерфейс v8.startupSnapshot
можно использовать для добавления крючков сериализации и десериализации для пользовательских стартовых снимков. В настоящее время снимки запуска могут быть встроены только в бинарный файл Node.js из исходного кода.
1 2 3 4 5 |
|
В приведенном примере entry.js
может использовать методы из интерфейса v8.startupSnapshot
, чтобы указать, как сохранить информацию для пользовательских объектов в снапшоте во время сериализации и как эта информация может быть использована для синхронизации этих объектов во время десериализации снапшота. Например, если entry.js
содержит следующий сценарий:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
Полученный двоичный файл просто выведет данные, десериализованные из моментального снимка при запуске:
1 2 3 |
|
В настоящее время API доступен только для экземпляра Node.js, запущенного из снапшота по умолчанию, то есть приложение, десериализованное из пользовательского снапшота, не сможет снова использовать эти API.
v8.startupSnapshot.addSerializeCallback(callback[, data])
¶
callback
<Function>
Обратный вызов, который будет вызван перед сериализацией.data
<any>
Необязательные данные, которые будут переданы вcallback
, когда он будет вызван.
Добавьте обратный вызов, который будет вызван, когда экземпляр Node.js будет сериализован в снимок и завершен. Это можно использовать для освобождения ресурсов, которые не должны или не могут быть сериализованы, или для преобразования пользовательских данных в форму, более подходящую для сериализации.
v8.startupSnapshot.addDeserializeCallback(callback[, data])
¶
callback
<Function>
Обратный вызов, который будет вызван после десериализации моментального снимка.data
<any>
Необязательные данные, которые будут переданы вcallback
при его вызове.
Добавьте обратный вызов, который будет вызываться, когда экземпляр Node.js будет десериализован из моментального снимка. Обратный вызов и data
(если предоставлены) будут сериализованы в снапшот, они могут быть использованы для повторной инициализации состояния приложения или для повторного получения ресурсов, необходимых приложению, когда приложение перезапускается из снапшота.
v8.startupSnapshot.setDeserializeMainFunction(callback[, data])
¶
callback
<Function>
Обратный вызов, который будет вызван в качестве точки входа после десериализации моментального снимка.data
<any>
Необязательные данные, которые будут переданы вcallback
при его вызове.
Это устанавливает точку входа приложения Node.js, когда оно десериализуется из моментального снимка. Это может быть вызвано только один раз в сценарии создания снапшота. При его вызове десериализованное приложение больше не нуждается в дополнительном сценарии точки входа для запуска и будет просто вызывать обратный вызов вместе с десериализованными данными (если они предоставлены), в противном случае сценарий точки входа все равно должен быть предоставлен десериализованному приложению.
v8.startupSnapshot.isBuildingSnapshot()
¶
- Возвращает:
<boolean>
.
Возвращает true, если экземпляр Node.js запущен для построения моментального снимка.
Класс: v8.GCProfiler
¶
Этот API собирает данные GC в текущем потоке.
new v8.GCProfiler()
¶
Создает новый экземпляр класса v8.GCProfiler
.
profiler.start()
¶
Начните собирать данные GC.
profiler.stop()
¶
Прекращает сбор данных GC и возвращает объект. Содержимое объекта следующее.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|
Вот пример.
1 2 3 4 5 6 |
|