SharedArrayBuffer
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. It’s been available across browsers since Dezember 2021.
* Some parts of this feature may have varying levels of support.
Das SharedArrayBuffer-Objekt wird verwendet, um einen generischen Rohdatenpuffer darzustellen, ähnlich dem ArrayBuffer-Objekt, jedoch so, dass sie zur Erstellung von Ansichten auf den gemeinsamen Speicher verwendet werden können. Ein SharedArrayBuffer ist kein Transferable Object, im Gegensatz zu einem ArrayBuffer, der übertragbar ist.
Beschreibung
Um Speicher mit SharedArrayBuffer-Objekten von einem Agenten im Cluster zu einem anderen zu teilen (ein Agent ist entweder das Hauptprogramm der Webseite oder einer ihrer Web-Worker), werden postMessage und structured cloning verwendet.
Der Structured Clone-Algorithmus akzeptiert SharedArrayBuffer-Objekte und typisierte Arrays, die auf SharedArrayBuffer-Objekte abgebildet sind. In beiden Fällen wird das SharedArrayBuffer-Objekt an den Empfänger übertragen, was zu einem neuen, privaten SharedArrayBuffer-Objekt im empfangenden Agenten führt (genau wie bei ArrayBuffer). Der gemeinsame Datenblock, auf den die beiden SharedArrayBuffer-Objekte verweisen, ist jedoch derselbe Datenblock, und eine Nebenwirkung auf den Block in einem Agenten wird schließlich im anderen Agenten sichtbar.
const sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
Gemeinsamer Speicher kann gleichzeitig in Workern oder dem Hauptthread erstellt und aktualisiert werden. Abhängig vom System (CPU, Betriebssystem, Browser) kann es eine Weile dauern, bis die Änderung in allen Kontexten propagiert wird. Um zu synchronisieren, sind atomare Operationen erforderlich.
SharedArrayBuffer-Objekte werden von einigen Web-APIs verwendet, wie z.B.:
Sicherheitsanforderungen
Gemeinsamer Speicher und hochauflösende Timer wurden effektiv Anfang 2018 deaktiviert im Lichte von 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 länger für SharedArrayBuffer-Objekte, und gemeinsamer Speicher über Threads hinweg ist somit verfügbar.
API-Verfügbarkeit
Abhängig davon, ob die oben genannten Sicherheitsmaßnahmen ergriffen werden, haben die verschiedenen Speicherfreigabe-APIs unterschiedliche Verfügbarkeiten:
- Das
Atomics-Objekt ist immer verfügbar. SharedArrayBuffer-Objekte sind prinzipiell immer verfügbar, aber leider ist der Konstruktor im globalen Objekt verborgen, sofern die beiden erwähnten Header nicht gesetzt sind, um die Kompatibilität mit Web-Inhalten zu gewährleisten. Es besteht die Hoffnung, dass diese Einschränkung in Zukunft entfernt werden kann.WebAssembly.Memorykann weiterhin verwendet werden, um eine Instanz zu erhalten.- Sofern die beiden erwähnten Header nicht gesetzt sind, werfen die verschiedenen
postMessage()-APIs fürSharedArrayBuffer-Objekte eine Ausnahme. Sind sie gesetzt, funktionierenpostMessage()beiWindow-Objekten und dedizierten Workern und erlauben das Teilen von Speicher.
WebAssembly Shared Memory
WebAssembly.Memory-Objekte können mit dem shared-Konstruktor-Flag erstellt werden. Wenn dieses Flag auf true gesetzt ist, kann das erzeugte Memory-Objekt zwischen Workern über postMessage() gemeinsam genutzt 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 eine neue Reihe von atomaren Anweisungen. Genau wie SharedArrayBuffer und seine Methoden bedingungslos aktiviert sind (und nur das Teilen zwischen Threads von den neuen Headern abhängt), sind die atomaren WebAssembly-Anweisungen ebenfalls bedingungslos erlaubt.
Wachsende SharedArrayBuffers
SharedArrayBuffer-Objekte können durch Einschließen 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ß es maximal sein kann, indem Sie auf seine growable und maxByteLength-Eigenschaften zugreifen. Sie können einem wachstumsfähigen SharedArrayBuffer mit einem grow()-Aufruf eine neue Größe zuweisen. Neue Bytes werden auf 0 initialisiert.
Diese Funktionen machen das Wachsen von SharedArrayBuffers effizienter — andernfalls müssten Sie eine Kopie des Puffers mit neuer Größe erstellen. Es bringt auch JavaScript auf Augenhöhe mit WebAssembly in dieser Hinsicht (Wasm-lineare Speicher können mit WebAssembly.Memory.prototype.grow() vergrößert werden).
Aus Sicherheitsgründen können SharedArrayBuffers nicht verkleinert, sondern nur vergrößert werden.
Konstruktor
-
Erzeugt ein neues
SharedArrayBuffer-Objekt.
Statische Eigenschaften
-
Gibt den Konstruktor zurück, der verwendet wird, um Rückgabewerte von
SharedArrayBuffer-Methoden zu konstruieren.
Instanzeigenschaften
Diese Eigenschaften sind auf SharedArrayBuffer.prototype definiert und werden von allen SharedArrayBuffer-Instanzen geteilt.
-
Die Größe des Arrays in Bytes. Diese wird festgelegt, wenn das Array erstellt wird und kann nur geändert werden, wenn der
SharedArrayBuffermit derSharedArrayBuffer.prototype.grow()-Methode wachstumsfähig ist. -
Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für
SharedArrayBuffer-Instanzen ist der Anfangswert derSharedArrayBuffer-Konstruktor. -
Schreibgeschützt. Gibt
truezurück, wenn derSharedArrayBuffervergrößert werden kann, oderfalsewenn nicht. -
Die schreibgeschützte maximale Länge in Bytes, auf die der
SharedArrayBuffervergrößert werden kann. Diese wird festgelegt, wenn das Array erstellt wird und kann nicht geändert werden. -
Der anfängliche Wert der
[Symbol.toStringTag]-Eigenschaft ist der String"SharedArrayBuffer". Diese Eigenschaft wird inObject.prototype.toString()verwendet.
Instanzmethoden
-
Erhöht den
SharedArrayBufferauf die angegebene Größe in Bytes. -
Gibt einen neuen
SharedArrayBufferzurück, dessen Inhalt eine Kopie der Bytes diesesSharedArrayBuffervonbegin, inklusive, bisend, exklusiv ist. Wennbeginoderendnegativ sind, bezieht es sich auf einen Index vom Ende des Arrays, im Gegensatz zum 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® 2026 Language Specification> # sec-sharedarraybuffer-objects> |
Browser-Kompatibilität
Siehe auch
AtomicsArrayBuffer- Leitfaden für JavaScript-typisierte Arrays
- Web-Worker
- Shared Memory – ein kurzer Leitfaden im TC39 ecmascript-sharedmem Vorschlag
- Ein Vorgeschmack auf JavaScripts neue parallele Primitiven 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)