SharedArrayBuffer
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.
* Some parts of this feature may have varying levels of support.
Das SharedArrayBuffer-Objekt wird verwendet, um einen generischen, rohen Binärdatenpuffer darzustellen, ähnlich dem ArrayBuffer-Objekt. Der Unterschied liegt darin, dass es ermöglicht, Ansichten auf gemeinsamen Speicher zu erstellen. Ein SharedArrayBuffer ist kein übertragbares Objekt im Gegensatz zu einem ArrayBuffer, das übertragbar ist.
Beschreibung
Um Speicher zwischen einem Agenten im Cluster und einem anderen zu teilen (ein Agent ist entweder das Hauptprogramm der Webseite oder einer ihrer Web-Worker), werden postMessage und strukturiertes Klonen verwendet.
Der Algorithmus zum strukturierten Klonen akzeptiert SharedArrayBuffer-Objekte und getypte Arrays, die auf SharedArrayBuffer-Objekte abgebildet sind. In beiden Fällen wird das SharedArrayBuffer-Objekt an den Empfänger übertragen, was in einem neuen, privaten SharedArrayBuffer-Objekt im empfangenden Agenten resultiert (ähnlich wie bei ArrayBuffer). Allerdings bezieht sich der gemeinsame Datenblock, auf den die beiden SharedArrayBuffer-Objekte verweisen, auf denselben Datenblock, und eine Nebenwirkung auf den Block in einem Agent wird schließlich im anderen Agent sichtbar.
const sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
Gemeinsamer Speicher kann gleichzeitig in Workern oder im Haupt-Thread erstellt und aktualisiert werden. Abhängig vom System (der CPU, dem Betriebssystem, dem Browser) kann es eine Weile dauern, bis die Änderung in allen Kontexten sichtbar wird. Zur Synchronisation sind Atomics-Operationen erforderlich.
SharedArrayBuffer-Objekte werden von einigen Web-APIs verwendet, wie zum Beispiel:
Sicherheitsanforderungen
Gemeinsamer Speicher und hochauflösende Timer wurden Anfang 2018 effektiv deaktiviert im Hinblick auf Spectre. Im Jahr 2020 wurde ein neuer, sicherer Ansatz standardisiert, um gemeinsamen Speicher wieder zu aktivieren.
Um gemeinsamen Speicher zu nutzen, muss Ihr Dokument in einem sicheren Kontext und cross-origin isoliert sein.
Sie können die Eigenschaften Window.crossOriginIsolated und WorkerGlobalScope.crossOriginIsolated verwenden, um zu überprüfen, ob das Dokument cross-origin isoliert ist:
const myWorker = new Worker("worker.js");
if (crossOriginIsolated) {
const buffer = new SharedArrayBuffer(16);
myWorker.postMessage(buffer);
} else {
const buffer = new ArrayBuffer(16);
myWorker.postMessage(buffer);
}
Wenn cross-origin isoliert, wirft postMessage() nicht mehr für SharedArrayBuffer-Objekte, und gemeinsamer Speicher über Threads ist daher verfügbar.
Verfügbarkeit der API
Je nachdem, ob die oben genannten Sicherheitsmaßnahmen getroffen werden, sind die verschiedenen Speicherfreigabe-APIs unterschiedlich verfügbar:
- Das
Atomics-Objekt ist immer verfügbar. SharedArrayBuffer-Objekte sind grundsätzlich immer verfügbar, aber leider ist der Konstruktor im globalen Objekt verborgen, es sei denn, die beiden oben genannten Header sind gesetzt, um die Kompatibilität mit Webinhalten zu gewährleisten. Es besteht die Hoffnung, dass diese Einschränkung in Zukunft aufgehoben werden kann.WebAssembly.Memorykann weiterhin verwendet werden, um eine Instanz zu erhalten.- Sofern die beiden oben genannten Header nicht gesetzt sind, werfen die verschiedenen
postMessage()-APIs beiSharedArrayBuffer-Objekten. Wenn sie gesetzt sind, funktionierenpostMessage()aufWindow-Objekten und dedizierten Workern und ermöglichen das Teilen von Speicher.
Gemeinsamer WebAssembly-Speicher
WebAssembly.Memory-Objekte können mit dem shared-Konstruktor-Flag erstellt werden. Wenn dieses Flag auf true gesetzt ist, kann das konstruierte Memory-Objekt zwischen Workern über postMessage() geteilt werden, genau wie SharedArrayBuffer, und der zugrunde liegende buffer des Memory-Objekts ist ein SharedArrayBuffer. Daher gelten die oben aufgeführten Anforderungen für das Teilen eines SharedArrayBuffer zwischen Workern auch für das Teilen eines WebAssembly.Memory.
Der WebAssembly Threads Vorschlag definiert auch einen neuen Satz von atomaren Anweisungen. Genau wie SharedArrayBuffer und seine Methoden bedingungslos aktiviert sind (und nur das Teilen zwischen Threads durch die neuen Header gesteuert wird), sind die WebAssembly-atomaren Anweisungen ebenfalls ohne Bedingungen erlaubt.
Wachstum von SharedArrayBuffers
SharedArrayBuffer-Objekte können durch Einbeziehung der maxByteLength-Option beim Aufruf des SharedArrayBuffer()-Konstruktors wachstumsfähig gemacht werden. Sie können abfragen, ob ein SharedArrayBuffer wachstumsfähig ist und wie groß seine maximale Größe ist, indem Sie auf seine growable- und maxByteLength-Eigenschaften zugreifen. Sie können einem wachstumsfähigen SharedArrayBuffer eine neue Größe zuweisen, indem Sie einen grow()-Aufruf machen. Neue Bytes werden auf 0 initialisiert.
Diese Funktionen machen das Wachstum von SharedArrayBuffers effizienter – andernfalls müssten Sie eine Kopie des Buffers mit einer neuen Größe erstellen. Sie geben JavaScript auch Parität mit WebAssembly in dieser Hinsicht (Wasm-Linearspeicher kann mit WebAssembly.Memory.prototype.grow() neugestaltet werden).
Aus Sicherheitsgründen können SharedArrayBuffers nicht verkleinert, sondern nur vergrößert werden.
Konstruktor
-
Erstellt ein neues
SharedArrayBuffer-Objekt.
Statische Eigenschaften
-
Gibt den Konstruktor zurück, der verwendet wird, um Rückgabewerte von
SharedArrayBuffer-Methoden zu konstruieren.
Instanz-Eigenschaften
Diese Eigenschaften sind auf SharedArrayBuffer.prototype definiert und werden von allen SharedArrayBuffer Instanzen geteilt.
-
Die Größe, in Bytes, des Arrays. Diese wird festgelegt, wenn das Array konstruiert wird und kann nur geändert werden, indem die
SharedArrayBuffer.prototype.grow()-Methode aufgerufen wird, wenn dasSharedArrayBufferwachstumsfähig ist. -
Die Konstruktorfunktion, die das Instanz-Objekt erstellt hat. Für
SharedArrayBuffer-Instanzen ist der Anfangswert derSharedArrayBuffer-Konstruktor. -
Schreibtgeschützt. Gibt
truezurück, wenn dasSharedArrayBuffervergrößert werden kann, oderfalse, wenn nicht. -
Die schreibgeschützte maximale Länge, in Bytes, auf die das
SharedArrayBuffervergrößert werden kann. Diese wird beim Konstruieren des Arrays festgelegt und kann nicht geändert werden. -
Der Anfangswert der
[Symbol.toStringTag]-Eigenschaft ist der String"SharedArrayBuffer". Diese Eigenschaft wird inObject.prototype.toString()verwendet.
Instanzmethoden
-
Vergrößert das
SharedArrayBufferauf die angegebene Größe, in Bytes. -
Gibt ein neues
SharedArrayBufferzurück, dessen Inhalt eine Kopie der Bytes diesesSharedArrayBuffervonbegin, inklusive, bisend, exklusiv ist. Wenn entwederbeginoderendnegativ sind, bezieht es sich auf einen Index vom Ende des Arrays, anstatt von Anfang.
Beispiele
Erstellen eines neuen SharedArrayBuffer
const sab = new SharedArrayBuffer(1024);
Ausschneiden des SharedArrayBuffer
sab.slice(); // SharedArrayBuffer { byteLength: 1024 }
sab.slice(2); // SharedArrayBuffer { byteLength: 1022 }
sab.slice(-2); // SharedArrayBuffer { byteLength: 2 }
sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }
Verwendung in einem WebGL-Puffer
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, sab, gl.STATIC_DRAW);
Spezifikationen
| Specification |
|---|
| ECMAScript® 2025 Language Specification # sec-sharedarraybuffer-objects |
Browser-Kompatibilität
Siehe auch
AtomicsArrayBuffer- JavaScript Typed Arrays Leitfaden
- Web Worker
- Shared Memory – eine kurze Anleitung im TC39 ecmascript-sharedmem-Vorschlag
- Ein Einblick in JavaScripts neue parallele Primitive auf hacks.mozilla.org (2016)
- COOP und COEP erklärt vom Chrome-Team (2020)
Cross-Origin-Opener-PolicyCross-Origin-Embedder-PolicyCross-Origin-Resource-PolicyWindow.crossOriginIsolatedundWorkerGlobalScope.crossOriginIsolated- SharedArrayBuffer-Updates in Android Chrome 88 und Desktop Chrome 92 auf developer.chrome.com (2021)