SharedArrayBuffer
Baseline
Weitgehend verfügbar
*
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Dezember 2021 browserübergreifend verfügbar.
* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.
Das SharedArrayBuffer-Objekt stellt einen generischen Puffer für binäre Rohdaten dar, ähnlich dem ArrayBuffer-Objekt. Im Unterschied dazu können mit ihm jedoch Ansichten auf gemeinsam genutzten Speicher erstellt werden. Ein SharedArrayBuffer ist kein übertragbares Objekt, anders als ein ArrayBuffer, der übertragen werden kann.
Beschreibung
Um Speicher mithilfe von SharedArrayBuffer-Objekten zwischen Agents desselben Clusters gemeinsam zu nutzen, werden postMessage und strukturiertes Klonen verwendet. Ein Agent ist entweder das Hauptprogramm der Webseite oder einer ihrer Web Worker.
Der Algorithmus für strukturiertes Klonen akzeptiert SharedArrayBuffer-Objekte sowie Typed Arrays, die auf SharedArrayBuffer-Objekte abgebildet sind. In beiden Fällen erhält der empfangende Agent ein neues, eigenes SharedArrayBuffer-Objekt – wie bei ArrayBuffer. Der gemeinsam genutzte Datenblock, auf den die beiden SharedArrayBuffer-Objekte verweisen, ist jedoch derselbe. Eine Änderung dieses Blocks durch einen Agent wird daher schließlich auch für den anderen Agent sichtbar.
const sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
Gemeinsam genutzter Speicher kann gleichzeitig in Workern und im Hauptthread erstellt und aktualisiert werden. Je nach System (CPU, Betriebssystem und Browser) kann es einige Zeit dauern, bis eine Änderung in allen Kontexten sichtbar wird. Zur Synchronisierung sind atomic-Operationen erforderlich.
SharedArrayBuffer-Objekte werden von einigen Web-APIs verwendet, darunter:
Sicherheitsanforderungen
Gemeinsam genutzter Speicher und hochauflösende Timer wurden angesichts von Spectre Anfang 2018 praktisch deaktiviert. Im Jahr 2020 wurde ein neuer, sicherer Ansatz standardisiert, um gemeinsam genutzten Speicher wieder zu ermöglichen.
Um gemeinsam genutzten Speicher zu verwenden, muss sich Ihr Dokument in einem sicheren Kontext befinden und Cross-Origin-isoliert sein.
Mit den Eigenschaften Window.crossOriginIsolated und WorkerGlobalScope.crossOriginIsolated können Sie prü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);
}
Bei Cross-Origin-Isolierung löst postMessage() für SharedArrayBuffer-Objekte keinen Fehler mehr aus. Damit steht gemeinsam genutzter Speicher über Threads hinweg zur Verfügung.
Verfügbarkeit der APIs
Je nachdem, ob die oben genannten Sicherheitsmaßnahmen umgesetzt wurden, sind die verschiedenen APIs zur gemeinsamen Speichernutzung unterschiedlich verfügbar:
- Das
Atomics-Objekt ist immer verfügbar. SharedArrayBuffer-Objekte sind grundsätzlich immer verfügbar. Aus Gründen der Kompatibilität mit Webinhalten ist der Konstruktor im globalen Objekt jedoch verborgen, sofern die beiden oben erwähnten Header nicht gesetzt sind. Möglicherweise kann diese Einschränkung künftig aufgehoben werden. ÜberWebAssembly.Memorylässt sich dennoch eine Instanz erhalten.- Solange die beiden oben erwähnten Header nicht gesetzt sind, lösen die verschiedenen
postMessage()-APIs beiSharedArrayBuffer-Objekten einen Fehler aus. Sind sie gesetzt, funktioniertpostMessage()beiWindow-Objekten und Dedicated Workern und ermöglicht die gemeinsame Speichernutzung.
Gemeinsam genutzter Speicher in WebAssembly
WebAssembly.Memory-Objekte können mit dem Konstruktor-Flag shared erstellt werden. Ist dieses Flag auf true gesetzt, kann das erstellte Memory-Objekt wie ein SharedArrayBuffer über postMessage() zwischen Workern geteilt werden. Der zugrunde liegende buffer des Memory-Objekts ist dabei ein SharedArrayBuffer. Die oben genannten Anforderungen für die gemeinsame Nutzung eines SharedArrayBuffer zwischen Workern gelten daher auch für die gemeinsame Nutzung eines WebAssembly.Memory-Objekts.
Der Vorschlag zu WebAssembly Threads definiert außerdem neue atomare Anweisungen. Ebenso wie SharedArrayBuffer und seine Methoden ohne Einschränkung verfügbar sind und nur die gemeinsame Nutzung zwischen Threads von den neuen Headern abhängt, sind auch die atomaren WebAssembly-Anweisungen ohne Einschränkung zulässig.
Vergrößerbare SharedArrayBuffers
SharedArrayBuffer-Objekte können vergrößerbar gemacht werden, indem beim Aufruf des Konstruktors SharedArrayBuffer() die Option maxByteLength angegeben wird. Ob ein SharedArrayBuffer vergrößerbar ist und wie groß er maximal werden kann, können Sie über seine Eigenschaften growable beziehungsweise maxByteLength abfragen. Mit einem Aufruf von grow() können Sie einem vergrößerbaren SharedArrayBuffer eine neue Größe zuweisen. Neue Bytes werden mit 0 initialisiert.
Diese Funktionen machen das Vergrößern von SharedArrayBuffer-Objekten effizienter – andernfalls müssten Sie eine Kopie des Puffers mit der neuen Größe erstellen. Außerdem erhält JavaScript damit in dieser Hinsicht dieselben Möglichkeiten wie WebAssembly (linearer Wasm-Speicher kann mit WebAssembly.Memory.prototype.grow() vergrößert werden).
Aus Sicherheitsgründen können SharedArrayBuffer-Objekte nur vergrößert, nicht verkleinert werden.
Konstruktor
-
Erstellt ein neues
SharedArrayBuffer-Objekt.
Statische Eigenschaften
-
Gibt den Konstruktor zurück, mit dem Rückgabewerte von
SharedArrayBuffer-Methoden erstellt werden.
Instanzeigenschaften
Diese Eigenschaften sind auf SharedArrayBuffer.prototype definiert und werden von allen SharedArrayBuffer-Instanzen gemeinsam genutzt.
-
Die Größe des Arrays in Bytes. Sie wird beim Erstellen des Arrays festgelegt und kann nur mit der Methode
SharedArrayBuffer.prototype.grow()geändert werden, wenn derSharedArrayBuffervergrößerbar ist. -
Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für
SharedArrayBuffer-Instanzen ist der Anfangswert der KonstruktorSharedArrayBuffer. -
Schreibgeschützt. Gibt
truezurück, wenn derSharedArrayBuffervergrößert werden kann, andernfallsfalse. -
Die schreibgeschützte maximale Länge in Bytes, auf die der
SharedArrayBuffervergrößert werden kann. Sie wird beim Erstellen des Arrays festgelegt und kann nicht geändert werden. -
Der Anfangswert der Eigenschaft
[Symbol.toStringTag]ist die Zeichenfolge"SharedArrayBuffer". Diese Eigenschaft wird vonObject.prototype.toString()verwendet.
Instanzmethoden
-
Vergrößert den
SharedArrayBufferauf die angegebene Größe in Bytes. -
Gibt einen neuen
SharedArrayBufferzurück, dessen Inhalt eine Kopie der Bytes diesesSharedArrayBuffervonbegin(einschließlich) bisend(ausschließlich) ist. Istbeginoderendnegativ, bezieht sich der Index auf das Ende statt auf den Anfang des Arrays.
Beispiele
Beachten Sie, dass diese Beispiele nicht direkt in der Konsole oder auf einer beliebigen Webseite ausgeführt werden können, da SharedArrayBuffer nur definiert ist, wenn seine Sicherheitsanforderungen erfüllt sind.
Einen neuen SharedArrayBuffer erstellen
const sab = new SharedArrayBuffer(1024);
Einen Ausschnitt aus dem SharedArrayBuffer erstellen
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
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-sharedarraybuffer-objects> |
Browser-Kompatibilität
Siehe auch
- Leitfaden zur Kommunikation und Koordination zwischen Agents
AtomicsArrayBuffer- Leitfaden zu Typed Arrays in JavaScript
- Web Workers
- Gemeinsam genutzter Speicher – eine kurze Einführung im TC39-Vorschlag ecmascript-sharedmem
- Ein Einblick in die neuen Parallelisierungsprimitive von JavaScript 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- Aktualisierungen für SharedArrayBuffer in Android Chrome 88 und Desktop Chrome 92 auf developer.chrome.com (2021)