V8
Quellcode: lib/v8.js
Das Modul node:v8
stellt APIs bereit, die spezifisch für die Version von V8 sind, die in die Node.js-Binärdatei eingebaut ist. Es kann folgendermaßen aufgerufen werden:
const v8 = require('node:v8');
v8.cachedDataVersionTag()
Hinzugefügt in: v8.0.0
- Gibt zurück: <integer>
Gibt eine Ganzzahl zurück, die ein Versions-Tag darstellt, das von der V8-Version, den Befehlszeilen-Flags und den erkannten CPU-Funktionen abgeleitet wurde. Dies ist nützlich, um festzustellen, ob ein vm.Script
cachedData
-Puffer mit dieser Instanz von V8 kompatibel ist.
console.log(v8.cachedDataVersionTag()); // 3947234607
// Der von v8.cachedDataVersionTag() zurückgegebene Wert wird von der V8-Version,
// den Befehlszeilen-Flags und den erkannten CPU-Funktionen abgeleitet. Testen Sie,
// ob sich der Wert tatsächlich ändert, wenn Flags umgeschaltet werden.
v8.setFlagsFromString('--allow_natives_syntax');
console.log(v8.cachedDataVersionTag()); // 183726201
v8.getHeapCodeStatistics()
Hinzugefügt in: v12.8.0
- Gibt zurück: <Object>
Ruft Statistiken über Code und seine Metadaten im Heap ab, siehe V8 GetHeapCodeAndMetadataStatistics
API. Gibt ein Objekt mit den folgenden Eigenschaften zurück:
code_and_metadata_size
<number>bytecode_and_metadata_size
<number>external_script_source_size
<number>cpu_profiler_metadata_size
<number>
{
code_and_metadata_size: 212208,
bytecode_and_metadata_size: 161368,
external_script_source_size: 1410794,
cpu_profiler_metadata_size: 0,
}
v8.getHeapSnapshot([options])
[History]
Version | Changes |
---|---|
v19.1.0 | Support für Optionen zur Konfiguration des Heap-Snapshots. |
v11.13.0 | Hinzugefügt in: v11.13.0 |
options
<Object>Gibt zurück: <stream.Readable> Ein Readable-Stream, der den serialisierten V8-Heap-Snapshot im JSON-Format enthält.
Generiert einen Snapshot des aktuellen V8-Heaps und gibt einen Readable-Stream zurück, der verwendet werden kann, um die JSON-serialisierte Darstellung zu lesen. Dieses JSON-Stream-Format ist für die Verwendung mit Werkzeugen wie den Chrome DevTools vorgesehen. Das JSON-Schema ist undokumentiert und spezifisch für die V8-Engine. Daher kann sich das Schema von einer V8-Version zur nächsten ändern.
Das Erstellen eines Heap-Snapshots erfordert etwa die doppelte Speichermenge der Heap-Größe zum Zeitpunkt der Snapshot-Erstellung. Dies birgt das Risiko, dass OOM-Killer den Prozess beenden.
Das Generieren eines Snapshots ist eine synchrone Operation, die die Ereignisschleife für eine Dauer blockiert, die von der Heap-Größe abhängt.
// Heap-Snapshot in die Konsole ausgeben
const v8 = require('node:v8');
const stream = v8.getHeapSnapshot();
stream.pipe(process.stdout);
v8.getHeapSpaceStatistics()
[History]
Version | Changes |
---|---|
v7.5.0 | Unterstützung für Werte, die den 32-Bit-Ganzzahlbereich ohne Vorzeichen überschreiten. |
v6.0.0 | Hinzugefügt in: v6.0.0 |
- Gibt zurück: <Object[]>
Gibt Statistiken über die V8-Heap-Bereiche zurück, d.h. die Segmente, aus denen der V8-Heap besteht. Weder die Reihenfolge der Heap-Bereiche noch die Verfügbarkeit eines Heap-Bereichs kann garantiert werden, da die Statistiken über die V8-Funktion GetHeapSpaceStatistics
bereitgestellt werden und sich von einer V8-Version zur nächsten ändern können.
Der zurückgegebene Wert ist ein Array von Objekten, das die folgenden Eigenschaften enthält:
space_name
<string>space_size
<number>space_used_size
<number>space_available_size
<number>physical_space_size
<number>
[
{
"space_name": "new_space",
"space_size": 2063872,
"space_used_size": 951112,
"space_available_size": 80824,
"physical_space_size": 2063872
},
{
"space_name": "old_space",
"space_size": 3090560,
"space_used_size": 2493792,
"space_available_size": 0,
"physical_space_size": 3090560
},
{
"space_name": "code_space",
"space_size": 1260160,
"space_used_size": 644256,
"space_available_size": 960,
"physical_space_size": 1260160
},
{
"space_name": "map_space",
"space_size": 1094160,
"space_used_size": 201608,
"space_available_size": 0,
"physical_space_size": 1094160
},
{
"space_name": "large_object_space",
"space_size": 0,
"space_used_size": 0,
"space_available_size": 1490980608,
"physical_space_size": 0
}
]
v8.getHeapStatistics()
[Historie]
Version | Änderungen |
---|---|
v7.5.0 | Unterstützung für Werte, die den 32-Bit-Integer-Bereich ohne Vorzeichen überschreiten. |
v7.2.0 | malloced_memory , peak_malloced_memory und does_zap_garbage hinzugefügt. |
v1.0.0 | Hinzugefügt in: v1.0.0 |
- Gibt zurück: <Object>
Gibt ein Objekt mit den folgenden Eigenschaften zurück:
total_heap_size
<number>total_heap_size_executable
<number>total_physical_size
<number>total_available_size
<number>used_heap_size
<number>heap_size_limit
<number>malloced_memory
<number>peak_malloced_memory
<number>does_zap_garbage
<number>number_of_native_contexts
<number>number_of_detached_contexts
<number>total_global_handles_size
<number>used_global_handles_size
<number>external_memory
<number>
total_heap_size
Der Wert von total_heap_size ist die Anzahl der Bytes, die V8 für den Heap zugewiesen hat. Dies kann wachsen, wenn used_heap mehr Speicher benötigt.
total_heap_size_executable
Der Wert von total_heap_size_executable ist der Teil des Heaps, der ausführbaren Code enthalten kann, in Bytes. Dies umfasst Speicher, der von JIT-kompiliertem Code verwendet wird, sowie Speicher, der ausführbar gehalten werden muss.
total_physical_size
Der Wert von total_physical_size ist der tatsächliche physische Speicher, der vom V8-Heap verwendet wird, in Bytes. Dies ist die Menge an Speicher, die zugesichert (oder verwendet) und nicht reserviert ist.
total_available_size
Der Wert von total_available_size ist die Anzahl der Bytes an Speicher, die dem V8-Heap zur Verfügung stehen. Dieser Wert stellt dar, wie viel mehr Speicher V8 verwenden kann, bevor er das Heap-Limit überschreitet.
used_heap_size
Der Wert von used_heap_size ist die Anzahl der Bytes, die derzeit von V8s JavaScript-Objekten verwendet werden. Dies ist der tatsächlich verwendete Speicher und enthält keinen Speicher, der zugewiesen, aber noch nicht verwendet wurde.
heap_size_limit
Der Wert von heap_size_limit ist die maximale Größe des V8-Heaps in Bytes (entweder das Standardlimit, das durch Systemressourcen bestimmt wird, oder der Wert, der an die Option --max_old_space_size
übergeben wurde).
malloced_memory
Der Wert von malloced_memory ist die Anzahl der Bytes, die von V8 über malloc
zugewiesen wurden.
peak_malloced_memory
Der Wert von peak_malloced_memory ist die maximale Anzahl von Bytes, die von V8 während der Lebensdauer des Prozesses über malloc
zugewiesen wurden.
does_zap_garbage
ist ein 0/1-Boolescher Wert, der angibt, ob die Option --zap_code_space
aktiviert ist oder nicht. Dadurch überschreibt V8 Heap-Garbage mit einem Bitmuster. Der RSS-Footprint (Resident Set Size) wird größer, da er kontinuierlich alle Heap-Seiten berührt, wodurch es unwahrscheinlicher wird, dass sie vom Betriebssystem ausgelagert werden.
number_of_native_contexts
Der Wert von native_context ist die Anzahl der aktuell aktiven Top-Level-Kontexte. Eine Zunahme dieser Zahl im Laufe der Zeit deutet auf ein Speicherleck hin.
number_of_detached_contexts
Der Wert von detached_context ist die Anzahl der Kontexte, die getrennt und noch nicht durch Garbage Collection bereinigt wurden. Wenn diese Zahl ungleich Null ist, deutet dies auf ein potenzielles Speicherleck hin.
total_global_handles_size
Der Wert von total_global_handles_size ist die gesamte Speichergröße der globalen V8-Handles.
used_global_handles_size
Der Wert von used_global_handles_size ist die verwendete Speichergröße der globalen V8-Handles.
external_memory
Der Wert von external_memory ist die Speichergröße von Array-Puffern und externen Zeichenketten.
{
total_heap_size: 7326976,
total_heap_size_executable: 4194304,
total_physical_size: 7326976,
total_available_size: 1152656,
used_heap_size: 3476208,
heap_size_limit: 1535115264,
malloced_memory: 16384,
peak_malloced_memory: 1127496,
does_zap_garbage: 0,
number_of_native_contexts: 1,
number_of_detached_contexts: 0,
total_global_handles_size: 8192,
used_global_handles_size: 3296,
external_memory: 318824
}
v8.queryObjects(ctor[, options])
Hinzugefügt in: v22.0.0, v20.13.0
[Stabil: 1 - Experimentell]
Stabil: 1 Stabilität: 1.1 - Aktive Entwicklung
ctor
<Function> Der Konstruktor, der verwendet werden kann, um in der Prototypenkette zu suchen, um Zielobjekte im Heap zu filtern.options
<undefined> | <Object>format
<string> Wenn es'count'
ist, wird die Anzahl der übereinstimmenden Objekte zurückgegeben. Wenn es'summary'
ist, wird ein Array mit Zusammenfassungsstrings der übereinstimmenden Objekte zurückgegeben.
Gibt zurück: {number|Array
Dies ähnelt der queryObjects()
Konsolen-API, die von der Chromium DevTools-Konsole bereitgestellt wird. Sie kann verwendet werden, um nach Objekten zu suchen, die den übereinstimmenden Konstruktor in ihrer Prototypenkette im Heap haben, nachdem eine vollständige Garbage Collection durchgeführt wurde, was für Regressionstests auf Speicherlecks nützlich sein kann. Um überraschende Ergebnisse zu vermeiden, sollten Benutzer die Verwendung dieser API für Konstruktoren vermeiden, deren Implementierung sie nicht kontrollieren, oder für Konstruktoren, die von anderen Parteien in der Anwendung aufgerufen werden können.
Um versehentliche Lecks zu vermeiden, gibt diese API keine rohen Referenzen auf die gefundenen Objekte zurück. Standardmäßig wird die Anzahl der gefundenen Objekte zurückgegeben. Wenn options.format
'summary'
ist, wird ein Array zurückgegeben, das kurze Stringdarstellungen für jedes Objekt enthält. Die in dieser API bereitgestellte Sichtbarkeit ähnelt der, die der Heap-Snapshot bietet, während Benutzer die Kosten für Serialisierung und Parsen sparen und die Zielobjekte während der Suche direkt filtern können.
Nur Objekte, die im aktuellen Ausführungskontext erstellt wurden, sind in den Ergebnissen enthalten.
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' }));
// Beachten Sie, dass, wenn es Kindklassen gibt, die von einem Konstruktor erben,
// der Konstruktor auch in der Prototypenkette des Prototyps der Kindklassen angezeigt wird,
// sodass der Prototyp der Kindklassen auch im Ergebnis enthalten wäre.
console.log(queryObjects(A)); // 3
// [ "B { foo: 'bar', bar: 'qux' }", 'A {}', "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));
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' }));
// Beachten Sie, dass, wenn es Kindklassen gibt, die von einem Konstruktor erben,
// der Konstruktor auch in der Prototypenkette des Prototyps der Kindklassen angezeigt wird,
// sodass der Prototyp der Kindklassen auch im Ergebnis enthalten wäre.
console.log(queryObjects(A)); // 3
// [ "B { foo: 'bar', bar: 'qux' }", 'A {}', "A { foo: 'bar' }" ]
console.log(queryObjects(A, { format: 'summary' }));
v8.setFlagsFromString(flags)
Hinzugefügt in: v1.0.0
flags
<string>
Die Methode v8.setFlagsFromString()
kann verwendet werden, um V8-Befehlszeilen-Flags programmatisch zu setzen. Diese Methode sollte mit Vorsicht verwendet werden. Das Ändern von Einstellungen, nachdem die VM gestartet wurde, kann zu unvorhersehbarem Verhalten führen, einschließlich Abstürzen und Datenverlust; oder es kann einfach nichts bewirken.
Die für eine Version von Node.js verfügbaren V8-Optionen können durch Ausführen von node --v8-options
ermittelt werden.
Verwendung:
// GC-Ereignisse eine Minute lang in stdout ausgeben.
const v8 = require('node:v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
v8.stopCoverage()
Hinzugefügt in: v15.1.0, v14.18.0, v12.22.0
Die Methode v8.stopCoverage()
ermöglicht es dem Benutzer, die von NODE_V8_COVERAGE
gestartete Coverage-Erfassung zu stoppen, sodass V8 die Ausführungszählungsdatensätze freigeben und den Code optimieren kann. Dies kann in Verbindung mit v8.takeCoverage()
verwendet werden, wenn der Benutzer die Coverage bei Bedarf erfassen möchte.
v8.takeCoverage()
Hinzugefügt in: v15.1.0, v14.18.0, v12.22.0
Die Methode v8.takeCoverage()
ermöglicht es dem Benutzer, die von NODE_V8_COVERAGE
gestartete Coverage bei Bedarf auf die Festplatte zu schreiben. Diese Methode kann während der Lebensdauer des Prozesses mehrmals aufgerufen werden. Jedes Mal wird der Ausführungszähler zurückgesetzt und ein neuer Coverage-Bericht in das von NODE_V8_COVERAGE
angegebene Verzeichnis geschrieben.
Wenn der Prozess kurz vor dem Beenden steht, wird dennoch ein letzter Coverage-Bericht auf die Festplatte geschrieben, es sei denn, v8.stopCoverage()
wird vor dem Beenden des Prozesses aufgerufen.
v8.writeHeapSnapshot([filename[,options]])
[Verlauf]
Version | Änderungen |
---|---|
v19.1.0 | Unterstützung von Optionen zur Konfiguration des Heap-Snapshots. |
v18.0.0 | Es wird jetzt eine Ausnahme ausgelöst, wenn die Datei nicht geschrieben werden konnte. |
v18.0.0 | Die zurückgegebenen Fehlercodes sind jetzt auf allen Plattformen konsistent. |
v11.13.0 | Hinzugefügt in: v11.13.0 |
filename
<string> Der Dateipfad, in dem der V8-Heap-Snapshot gespeichert werden soll. Wenn nicht angegeben, wird ein Dateiname mit dem Muster'Heap-${yyyymmdd}-${hhmmss}-${pid}-${thread_id}.heapsnapshot'
generiert, wobei{pid}
die PID des Node.js-Prozesses und{thread_id}
0
ist, wennwriteHeapSnapshot()
vom Haupt-Node.js-Thread oder der ID eines Worker-Threads aufgerufen wird.options
<Object>Gibt zurück: <string> Der Dateiname, unter dem der Snapshot gespeichert wurde.
Generiert einen Snapshot des aktuellen V8-Heaps und schreibt ihn in eine JSON-Datei. Diese Datei ist für die Verwendung mit Tools wie Chrome DevTools vorgesehen. Das JSON-Schema ist undokumentiert und spezifisch für die V8-Engine und kann sich von einer V8-Version zur nächsten ändern.
Ein Heap-Snapshot ist spezifisch für ein einzelnes V8-Isolat. Bei Verwendung von Worker-Threads enthält ein vom Hauptthread generierter Heap-Snapshot keine Informationen über die Worker und umgekehrt.
Das Erstellen eines Heap-Snapshots erfordert etwa die doppelte Speichermenge des Heaps zum Zeitpunkt der Erstellung des Snapshots. Dies birgt das Risiko, dass OOM-Killer den Prozess beenden.
Das Generieren eines Snapshots ist ein synchroner Vorgang, der die Ereignisschleife für eine Dauer blockiert, die von der Heap-Größe abhängt.
const { writeHeapSnapshot } = require('node:v8');
const {
Worker,
isMainThread,
parentPort,
} = require('node:worker_threads');
if (isMainThread) {
const worker = new Worker(__filename);
worker.once('message', (filename) => {
console.log(`worker heapdump: ${filename}`);
// Now get a heapdump for the main thread.
console.log(`main thread heapdump: ${writeHeapSnapshot()}`);
});
// Tell the worker to create a heapdump.
worker.postMessage('heapdump');
} else {
parentPort.once('message', (message) => {
if (message === 'heapdump') {
// Generate a heapdump for the worker
// and return the filename to the parent.
parentPort.postMessage(writeHeapSnapshot());
}
});
}
v8.setHeapSnapshotNearHeapLimit(limit)
Hinzugefügt in: v18.10.0, v16.18.0
[Stabil: 1 - Experimentell]
Stabil: 1 Stabilität: 1 - Experimentell
limit
<integer>
Die API ist eine No-Op, wenn --heapsnapshot-near-heap-limit
bereits über die Kommandozeile gesetzt wurde oder die API mehr als einmal aufgerufen wird. limit
muss eine positive Ganzzahl sein. Siehe --heapsnapshot-near-heap-limit
für weitere Informationen.
Serialisierungs-API
Die Serialisierungs-API bietet Mittel zur Serialisierung von JavaScript-Werten in einer Weise, die mit dem HTML-Algorithmus für strukturierte Klone kompatibel ist.
Das Format ist abwärtskompatibel (d.h. sicher zum Speichern auf der Festplatte). Gleiche JavaScript-Werte können zu unterschiedlichen serialisierten Ausgaben führen.
v8.serialize(value)
Hinzugefügt in: v8.0.0
Verwendet einen DefaultSerializer
, um value
in einen Puffer zu serialisieren.
ERR_BUFFER_TOO_LARGE
wird ausgelöst, wenn versucht wird, ein riesiges Objekt zu serialisieren, das einen Puffer benötigt, der größer ist als buffer.constants.MAX_LENGTH
.
v8.deserialize(buffer)
Hinzugefügt in: v8.0.0
buffer
<Buffer> | <TypedArray> | <DataView> Ein Puffer, der vonserialize()
zurückgegeben wird.
Verwendet einen DefaultDeserializer
mit Standardoptionen, um einen JS-Wert aus einem Puffer zu lesen.
Klasse: v8.Serializer
Hinzugefügt in: v8.0.0
new Serializer()
Erstellt ein neues Serializer
-Objekt.
serializer.writeHeader()
Schreibt einen Header, der die Versionsnummer des Serialisierungsformats enthält.
serializer.writeValue(value)
value
<any>
Serialisiert einen JavaScript-Wert und fügt die serialisierte Repräsentation zum internen Puffer hinzu.
Dies wirft einen Fehler, wenn value
nicht serialisiert werden kann.
serializer.releaseBuffer()
- Gibt zurück: <Buffer>
Gibt den gespeicherten internen Puffer zurück. Dieser Serialisierer sollte nicht mehr verwendet werden, sobald der Puffer freigegeben wurde. Der Aufruf dieser Methode führt zu undefiniertem Verhalten, wenn ein vorheriger Schreibvorgang fehlgeschlagen ist.
serializer.transferArrayBuffer(id, arrayBuffer)
id
<integer> Eine 32-Bit-Ganzzahl ohne Vorzeichen.arrayBuffer
<ArrayBuffer> EineArrayBuffer
-Instanz.
Markiert ein ArrayBuffer
als außerhalb des Bandes übertragen. Übergeben Sie das entsprechende ArrayBuffer
im Deserialisierungskontext an deserializer.transferArrayBuffer()
.
serializer.writeUint32(value)
value
<integer>
Schreibt eine rohe 32-Bit-Ganzzahl ohne Vorzeichen. Zur Verwendung innerhalb eines benutzerdefinierten serializer._writeHostObject()
.
serializer.writeUint64(hi, lo)
Schreibt eine rohe 64-Bit-Ganzzahl ohne Vorzeichen, aufgeteilt in hohe und niedrige 32-Bit-Teile. Zur Verwendung innerhalb eines benutzerdefinierten serializer._writeHostObject()
.
serializer.writeDouble(value)
value
<number>
Schreibt einen JS number
-Wert. Zur Verwendung innerhalb eines benutzerdefinierten serializer._writeHostObject()
.
serializer.writeRawBytes(buffer)
buffer
<Buffer> | <TypedArray> | <DataView>
Schreibt rohe Bytes in den internen Puffer des Serialisierers. Der Deserialisierer benötigt eine Möglichkeit, die Länge des Puffers zu berechnen. Zur Verwendung innerhalb eines benutzerdefinierten serializer._writeHostObject()
.
serializer._writeHostObject(object)
object
<Object>
Diese Methode wird aufgerufen, um eine Art Host-Objekt zu schreiben, d. h. ein Objekt, das durch native C++-Bindings erstellt wurde. Wenn es nicht möglich ist, object
zu serialisieren, sollte eine geeignete Ausnahme geworfen werden.
Diese Methode ist nicht in der Serializer
-Klasse selbst vorhanden, kann aber von Unterklassen bereitgestellt werden.
serializer._getDataCloneError(message)
message
<string>
Diese Methode wird aufgerufen, um Fehlerobjekte zu erzeugen, die geworfen werden, wenn ein Objekt nicht geklont werden kann.
Diese Methode verwendet standardmäßig den Error
-Konstruktor und kann in Unterklassen überschrieben werden.
serializer._getSharedArrayBufferId(sharedArrayBuffer)
sharedArrayBuffer
<SharedArrayBuffer>
Diese Methode wird aufgerufen, wenn der Serialisierer ein SharedArrayBuffer
-Objekt serialisieren will. Sie muss eine vorzeichenlose 32-Bit-Integer-ID für das Objekt zurückgeben, wobei dieselbe ID verwendet wird, wenn dieses SharedArrayBuffer
bereits serialisiert wurde. Beim Deserialisieren wird diese ID an deserializer.transferArrayBuffer()
übergeben.
Wenn das Objekt nicht serialisiert werden kann, sollte eine Ausnahme geworfen werden.
Diese Methode ist nicht in der Serializer
-Klasse selbst vorhanden, kann aber von Unterklassen bereitgestellt werden.
serializer._setTreatArrayBufferViewsAsHostObjects(flag)
flag
<boolean> Standardwert:false
Gibt an, ob TypedArray
- und DataView
-Objekte als Hostobjekte behandelt werden sollen, d. h. ob sie an serializer._writeHostObject()
übergeben werden sollen.
Klasse: v8.Deserializer
Hinzugefügt in: v8.0.0
new Deserializer(buffer)
buffer
<Buffer> | <TypedArray> | <DataView> Ein Buffer, der vonserializer.releaseBuffer()
zurückgegeben wird.
Erstellt ein neues Deserializer
-Objekt.
deserializer.readHeader()
Liest und validiert einen Header (einschließlich der Formatversion). Kann beispielsweise ein ungültiges oder nicht unterstütztes Wire-Format ablehnen. In diesem Fall wird ein Error
ausgelöst.
deserializer.readValue()
Deserialisiert einen JavaScript-Wert aus dem Buffer und gibt ihn zurück.
deserializer.transferArrayBuffer(id, arrayBuffer)
id
<integer> Eine 32-Bit-Ganzzahl ohne Vorzeichen.arrayBuffer
<ArrayBuffer> | <SharedArrayBuffer> EineArrayBuffer
-Instanz.
Markiert einen ArrayBuffer
, dessen Inhalt außerhalb des Bandes übertragen wurde. Übergeben Sie den entsprechenden ArrayBuffer
im Serialisierungskontext an serializer.transferArrayBuffer()
(oder geben Sie die id
von serializer._getSharedArrayBufferId()
im Fall von SharedArrayBuffer
s zurück).
deserializer.getWireFormatVersion()
- Gibt zurück: <integer>
Liest die zugrunde liegende Wire-Format-Version. Wahrscheinlich hauptsächlich nützlich für Legacy-Code, der alte Wire-Format-Versionen liest. Darf nicht vor .readHeader()
aufgerufen werden.
deserializer.readUint32()
- Gibt zurück: <integer>
Liest eine rohe 32-Bit vorzeichenlose Ganzzahl und gibt sie zurück. Zur Verwendung innerhalb eines benutzerdefinierten deserializer._readHostObject()
.
deserializer.readUint64()
- Gibt zurück: <integer[]>
Liest eine rohe 64-Bit vorzeichenlose Ganzzahl und gibt sie als Array [hi, lo]
mit zwei 32-Bit vorzeichenlosen Ganzzahleinträgen zurück. Zur Verwendung innerhalb eines benutzerdefinierten deserializer._readHostObject()
.
deserializer.readDouble()
- Gibt zurück: <number>
Liest einen JS number
-Wert. Zur Verwendung innerhalb eines benutzerdefinierten deserializer._readHostObject()
.
deserializer.readRawBytes(length)
Liest rohe Bytes aus dem internen Puffer des Deserialisierers. Der Parameter length
muss der Länge des Puffers entsprechen, der an serializer.writeRawBytes()
übergeben wurde. Zur Verwendung innerhalb eines benutzerdefinierten deserializer._readHostObject()
.
deserializer._readHostObject()
Diese Methode wird aufgerufen, um eine Art Host-Objekt zu lesen, d. h. ein Objekt, das durch native C++-Bindungen erstellt wird. Wenn es nicht möglich ist, die Daten zu deserialisieren, sollte eine geeignete Ausnahme ausgelöst werden.
Diese Methode ist nicht in der Klasse Deserializer
selbst vorhanden, kann aber von Unterklassen bereitgestellt werden.
Klasse: v8.DefaultSerializer
Hinzugefügt in: v8.0.0
Eine Unterklasse von Serializer
, die TypedArray
-Objekte (insbesondere Buffer
) und DataView
-Objekte als Host-Objekte serialisiert und nur den Teil ihrer zugrunde liegenden ArrayBuffer
speichert, auf den sie sich beziehen.
Klasse: v8.DefaultDeserializer
Hinzugefügt in: v8.0.0
Eine Unterklasse von Deserializer
, die dem Format entspricht, das von DefaultSerializer
geschrieben wurde.
Promise-Hooks
Die promiseHooks
-Schnittstelle kann verwendet werden, um Lebenszyklusereignisse von Promises zu verfolgen. Um alle asynchronen Aktivitäten zu verfolgen, siehe async_hooks
, das intern dieses Modul verwendet, um Promise-Lebenszyklusereignisse zusätzlich zu Ereignissen für andere asynchrone Ressourcen zu erzeugen. Für die Verwaltung des Request-Kontexts siehe AsyncLocalStorage
.
import { promiseHooks } from 'node:v8';
// Es gibt vier Lebenszyklusereignisse, die von Promises erzeugt werden:
// Das `init`-Ereignis stellt die Erstellung eines Promises dar. Dies kann eine
// direkte Erstellung sein, wie z. B. mit `new Promise(...)` oder eine Fortsetzung,
// wie z. B. `then()` oder `catch()`. Es tritt auch auf, wenn eine asynchrone Funktion
// aufgerufen wird oder ein `await` ausführt. Wenn ein Fortsetzungs-Promise erstellt wird,
// ist `parent` das Promise, von dem es eine Fortsetzung ist.
function init(promise, parent) {
console.log('ein Promise wurde erstellt', { promise, parent });
}
// Das `settled`-Ereignis tritt ein, wenn ein Promise einen Auflösungs- oder
// Ablehnungswert empfängt. Dies kann synchron geschehen, z. B. bei Verwendung von
// `Promise.resolve()` für Nicht-Promise-Eingaben.
function settled(promise) {
console.log('ein Promise wurde aufgelöst oder abgelehnt', { promise });
}
// Das `before`-Ereignis wird unmittelbar vor der Ausführung eines `then()`- oder
// `catch()`-Handlers oder der Wiederaufnahme der Ausführung durch ein `await` ausgeführt.
function before(promise) {
console.log('ein Promise ist im Begriff, einen then-Handler aufzurufen', { promise });
}
// Das `after`-Ereignis wird unmittelbar nach der Ausführung eines `then()`-Handlers
// oder beim Beginn eines `await` nach der Wiederaufnahme von einem anderen ausgeführt.
function after(promise) {
console.log('ein Promise hat die Ausführung eines then-Handlers beendet', { promise });
}
// Lebenszyklus-Hooks können einzeln gestartet und gestoppt werden
const stopWatchingInits = promiseHooks.onInit(init);
const stopWatchingSettleds = promiseHooks.onSettled(settled);
const stopWatchingBefores = promiseHooks.onBefore(before);
const stopWatchingAfters = promiseHooks.onAfter(after);
// Oder sie können in Gruppen gestartet und gestoppt werden
const stopHookSet = promiseHooks.createHook({
init,
settled,
before,
after,
});
// Um einen Hook zu stoppen, rufen Sie die Funktion auf, die bei seiner Erstellung zurückgegeben wurde.
stopWatchingInits();
stopWatchingSettleds();
stopWatchingBefores();
stopWatchingAfters();
stopHookSet();
promiseHooks.onInit(init)
Hinzugefügt in: v17.1.0, v16.14.0
init
<Funktion> Derinit
-Callback, der aufgerufen wird, wenn ein Promise erstellt wird.- Gibt zurück: <Funktion> Aufruf zum Stoppen des Hooks.
Der init
-Hook muss eine einfache Funktion sein. Die Bereitstellung einer Async-Funktion löst einen Fehler aus, da dies zu einer unendlichen Microtask-Schleife führen würde.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onInit((promise, parent) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onInit((promise, parent) => {});
promiseHooks.onSettled(settled)
Hinzugefügt in: v17.1.0, v16.14.0
settled
<Funktion> Dersettled
-Callback, der aufgerufen wird, wenn ein Promise aufgelöst oder abgelehnt wird.- Gibt zurück: <Funktion> Aufruf zum Stoppen des Hooks.
Der settled
-Hook muss eine einfache Funktion sein. Die Bereitstellung einer Async-Funktion löst einen Fehler aus, da dies zu einer unendlichen Microtask-Schleife führen würde.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onSettled((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onSettled((promise) => {});
promiseHooks.onBefore(before)
Hinzugefügt in: v17.1.0, v16.14.0
before
<Funktion> Derbefore
-Callback, der aufgerufen wird, bevor eine Promise-Fortsetzung ausgeführt wird.- Gibt zurück: <Funktion> Aufruf zum Stoppen des Hooks.
Der before
-Hook muss eine einfache Funktion sein. Die Bereitstellung einer Async-Funktion löst einen Fehler aus, da dies zu einer unendlichen Microtask-Schleife führen würde.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onBefore((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onBefore((promise) => {});
promiseHooks.onAfter(after)
Hinzugefügt in: v17.1.0, v16.14.0
after
<Function> Derafter
-Callback, der nach der Ausführung einer Promise-Fortsetzung aufgerufen wird.- Gibt zurück: <Function> Aufruf, um den Hook zu stoppen.
Der after
-Hook muss eine einfache Funktion sein. Die Bereitstellung einer Async-Funktion wirft einen Fehler, da dies zu einer unendlichen Microtask-Schleife führen würde.
import { promiseHooks } from 'node:v8';
const stop = promiseHooks.onAfter((promise) => {});
const { promiseHooks } = require('node:v8');
const stop = promiseHooks.onAfter((promise) => {});
promiseHooks.createHook(callbacks)
Hinzugefügt in: v17.1.0, v16.14.0
callbacks
<Object> Die zu registrierenden Hook-Callbacksinit
<Function> Derinit
-Callback.before
<Function> Derbefore
-Callback.after
<Function> Derafter
-Callback.settled
<Function> Dersettled
-Callback.
Gibt zurück: <Function> Wird zum Deaktivieren von Hooks verwendet
Die Hook-Callbacks müssen einfache Funktionen sein. Die Bereitstellung von Async-Funktionen wirft einen Fehler, da dies zu einer unendlichen Microtask-Schleife führen würde.
Registriert Funktionen, die für verschiedene Lebensdauerereignisse jeder Promise aufgerufen werden sollen.
Die Callbacks init()
/before()
/after()
/settled()
werden für die jeweiligen Ereignisse während der Lebensdauer einer Promise aufgerufen.
Alle Callbacks sind optional. Wenn beispielsweise nur die Erstellung von Promise verfolgt werden muss, muss nur der init
-Callback übergeben werden. Die Besonderheiten aller Funktionen, die an callbacks
übergeben werden können, finden Sie im Abschnitt Hook-Callbacks.
import { promiseHooks } from 'node:v8';
const stopAll = promiseHooks.createHook({
init(promise, parent) {},
});
const { promiseHooks } = require('node:v8');
const stopAll = promiseHooks.createHook({
init(promise, parent) {},
});
Hook-Rückrufe
Schlüsselereignisse im Lebenszyklus eines Promise wurden in vier Bereiche kategorisiert: Erstellung eines Promise, vor/nachdem ein Fortsetzungshandler aufgerufen wird oder rund um ein await
, und wenn das Promise aufgelöst oder abgelehnt wird.
Obwohl diese Hooks denen von async_hooks
ähneln, fehlt ihnen ein destroy
-Hook. Andere Arten von asynchronen Ressourcen repräsentieren typischerweise Sockets oder Dateideskriptoren, die einen deutlichen "geschlossenen" Zustand haben, um das destroy
-Lebenszyklusereignis auszudrücken, während Promises so lange verwendbar bleiben, wie Code sie noch erreichen kann. Garbage Collection Tracking wird verwendet, um Promises in das async_hooks
-Ereignismodell einzupassen, aber dieses Tracking ist sehr teuer und sie werden möglicherweise nie garbage-collected.
Da Promises asynchrone Ressourcen sind, deren Lebenszyklus über den Promise-Hooks-Mechanismus verfolgt wird, dürfen die init()
, before()
, after()
und settled()
Rückrufe keine asynchronen Funktionen sein, da sie weitere Promises erstellen würden, die eine Endlosschleife erzeugen würden.
Obwohl diese API verwendet wird, um Promise-Ereignisse in async_hooks
einzuspeisen, ist die Reihenfolge zwischen den beiden undefiniert. Beide APIs sind Mandantenfähig und könnten daher Ereignisse in beliebiger Reihenfolge zueinander erzeugen.
init(promise, parent)
promise
<Promise> Das Promise, das erstellt wird.parent
<Promise> Das Promise, von dem fortgesetzt wurde, falls zutreffend.
Wird aufgerufen, wenn ein Promise konstruiert wird. Dies bedeutet nicht, dass entsprechende before
/after
-Ereignisse auftreten, sondern nur, dass die Möglichkeit besteht. Dies geschieht, wenn ein Promise erstellt wird, ohne jemals eine Fortsetzung zu erhalten.
before(promise)
promise
<Promise>
Wird aufgerufen, bevor eine Promise-Fortsetzung ausgeführt wird. Dies kann in Form von then()
, catch()
oder finally()
Handlern oder einem await
Resuming erfolgen.
Der before
-Rückruf wird 0 bis N Mal aufgerufen. Der before
-Rückruf wird in der Regel 0 Mal aufgerufen, wenn noch nie eine Fortsetzung für das Promise erstellt wurde. Der before
-Rückruf kann viele Male aufgerufen werden, wenn viele Fortsetzungen vom selben Promise erstellt wurden.
after(promise)
promise
<Promise>
Wird unmittelbar nach der Ausführung einer Promise-Fortsetzung aufgerufen. Dies kann nach einem then()
, catch()
oder finally()
-Handler oder vor einem await
nach einem anderen await
geschehen.
settled(promise)
promise
<Promise>
Wird aufgerufen, wenn die Promise einen Auflösungs- oder Ablehnungswert empfängt. Dies kann synchron im Fall von Promise.resolve()
oder Promise.reject()
auftreten.
Startup Snapshot API
Hinzugefügt in: v18.6.0, v16.17.0
[Stabil: 1 - Experimentell]
Stabil: 1 Stabilität: 1 - Experimentell
Die v8.startupSnapshot
-Schnittstelle kann verwendet werden, um Serialisierungs- und Deserialisierungshooks für benutzerdefinierte Startup-Snapshots hinzuzufügen.
$ node --snapshot-blob snapshot.blob --build-snapshot entry.js
# Dies startet einen Prozess mit dem Snapshot {#this-launches-a-process-with-the-snapshot}
$ node --snapshot-blob snapshot.blob
Im obigen Beispiel kann entry.js
Methoden der v8.startupSnapshot
-Schnittstelle verwenden, um anzugeben, wie Informationen für benutzerdefinierte Objekte im Snapshot während der Serialisierung gespeichert werden sollen und wie die Informationen verwendet werden können, um diese Objekte während der Deserialisierung des Snapshots zu synchronisieren. Wenn beispielsweise entry.js
das folgende Skript enthält:
'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();
// Lesen einer Reihe von Dateien aus dem Verzeichnis und Speichern in 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 ist hier, wo das Snapshot-Skript platziert wird
// während der Snapshot-Erstellungszeit.
const shelf = new BookShelf(__dirname, [
'book1.en_US.txt',
'book1.es_ES.txt',
'book2.zh_CN.txt',
]);
assert(v8.startupSnapshot.isBuildingSnapshot());
// Bei der Snapshot-Serialisierung werden die Bücher komprimiert, um die Größe zu reduzieren.
v8.startupSnapshot.addSerializeCallback(BookShelf.compressAll, shelf);
// Bei der Snapshot-Deserialisierung werden die Bücher dekomprimiert.
v8.startupSnapshot.addDeserializeCallback(BookShelf.decompressAll, shelf);
v8.startupSnapshot.setDeserializeMainFunction((shelf) => {
// process.env und process.argv werden während des Snapshots aktualisiert
// Deserialisierung.
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);
Die resultierende Binärdatei gibt die aus dem Snapshot deserialisierten Daten während des Starts aus, wobei die aktualisierten process.env
und process.argv
des gestarteten Prozesses verwendet werden:
$ BOOK_LANG=es_ES node --snapshot-blob snapshot.blob book1
# Gibt den Inhalt von book1.es_ES.txt aus, der aus dem Snapshot deserialisiert wurde. {#prints-content-of-book1es_estxt-deserialized-from-the-snapshot}
Derzeit kann die Anwendung, die von einem User-Land-Snapshot deserialisiert wurde, nicht erneut gesnapshottet werden, daher sind diese APIs nur für Anwendungen verfügbar, die nicht von einem User-Land-Snapshot deserialisiert werden.
v8.startupSnapshot.addSerializeCallback(callback[, data])
Hinzugefügt in: v18.6.0, v16.17.0
callback
<Function> Callback, die vor der Serialisierung aufgerufen wird.data
<any> Optionale Daten, die an dencallback
übergeben werden, wenn er aufgerufen wird.
Fügt einen Callback hinzu, der aufgerufen wird, wenn die Node.js-Instanz in einen Snapshot serialisiert und beendet werden soll. Dies kann verwendet werden, um Ressourcen freizugeben, die nicht serialisiert werden sollten oder können, oder um Benutzerdaten in eine Form umzuwandeln, die besser für die Serialisierung geeignet ist.
Callbacks werden in der Reihenfolge ausgeführt, in der sie hinzugefügt werden.
v8.startupSnapshot.addDeserializeCallback(callback[, data])
Hinzugefügt in: v18.6.0, v16.17.0
callback
<Function> Callback, die nach der Deserialisierung des Snapshots aufgerufen wird.data
<any> Optionale Daten, die an dencallback
übergeben werden, wenn er aufgerufen wird.
Fügt einen Callback hinzu, der aufgerufen wird, wenn die Node.js-Instanz aus einem Snapshot deserialisiert wird. Der callback
und die data
(falls vorhanden) werden in den Snapshot serialisiert. Sie können verwendet werden, um den Zustand der Anwendung neu zu initialisieren oder um Ressourcen neu zu beschaffen, die die Anwendung benötigt, wenn die Anwendung aus dem Snapshot neu gestartet wird.
Callbacks werden in der Reihenfolge ausgeführt, in der sie hinzugefügt werden.
v8.startupSnapshot.setDeserializeMainFunction(callback[, data])
Hinzugefügt in: v18.6.0, v16.17.0
callback
<Function> Callback, die als Einstiegspunkt nach der Deserialisierung des Snapshots aufgerufen wird.data
<any> Optionale Daten, die an dencallback
übergeben werden, wenn er aufgerufen wird.
Dies legt den Einstiegspunkt der Node.js-Anwendung fest, wenn sie aus einem Snapshot deserialisiert wird. Dies kann nur einmal im Snapshot-Erstellungsskript aufgerufen werden. Wenn dies aufgerufen wird, benötigt die deserialisierte Anwendung kein zusätzliches Einstiegspunkt-Skript mehr, um zu starten, und ruft einfach den Callback zusammen mit den deserialisierten Daten (falls vorhanden) auf. Andernfalls muss der deserialisierten Anwendung weiterhin ein Einstiegspunkt-Skript bereitgestellt werden.
v8.startupSnapshot.isBuildingSnapshot()
Hinzugefügt in: v18.6.0, v16.17.0
- Gibt zurück: <boolean>
Gibt true zurück, wenn die Node.js-Instanz zum Erstellen eines Snapshots ausgeführt wird.
Klasse: v8.GCProfiler
Hinzugefügt in: v19.6.0, v18.15.0
Diese API sammelt GC-Daten im aktuellen Thread.
new v8.GCProfiler()
Hinzugefügt in: v19.6.0, v18.15.0
Erstellt eine neue Instanz der Klasse v8.GCProfiler
.
profiler.start()
Hinzugefügt in: v19.6.0, v18.15.0
Startet das Sammeln von GC-Daten.
profiler.stop()
Hinzugefügt in: v19.6.0, v18.15.0
Beendet das Sammeln von GC-Daten und gibt ein Objekt zurück. Der Inhalt des Objekts ist wie folgt.
{
"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
}
Hier ist ein Beispiel.
const { GCProfiler } = require('node:v8');
const profiler = new GCProfiler();
profiler.start();
setTimeout(() => {
console.log(profiler.stop());
}, 1000);