Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

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.

js
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:

js
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. Über WebAssembly.Memory lässt sich dennoch eine Instanz erhalten.
  • Solange die beiden oben erwähnten Header nicht gesetzt sind, lösen die verschiedenen postMessage()-APIs bei SharedArrayBuffer-Objekten einen Fehler aus. Sind sie gesetzt, funktioniert postMessage() bei Window-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

SharedArrayBuffer()

Erstellt ein neues SharedArrayBuffer-Objekt.

Statische Eigenschaften

SharedArrayBuffer[Symbol.species]

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.

SharedArrayBuffer.prototype.byteLength

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 der SharedArrayBuffer vergrößerbar ist.

SharedArrayBuffer.prototype.constructor

Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für SharedArrayBuffer-Instanzen ist der Anfangswert der Konstruktor SharedArrayBuffer.

SharedArrayBuffer.prototype.growable

Schreibgeschützt. Gibt true zurück, wenn der SharedArrayBuffer vergrößert werden kann, andernfalls false.

SharedArrayBuffer.prototype.maxByteLength

Die schreibgeschützte maximale Länge in Bytes, auf die der SharedArrayBuffer vergrößert werden kann. Sie wird beim Erstellen des Arrays festgelegt und kann nicht geändert werden.

SharedArrayBuffer.prototype[Symbol.toStringTag]

Der Anfangswert der Eigenschaft [Symbol.toStringTag] ist die Zeichenfolge "SharedArrayBuffer". Diese Eigenschaft wird von Object.prototype.toString() verwendet.

Instanzmethoden

SharedArrayBuffer.prototype.grow()

Vergrößert den SharedArrayBuffer auf die angegebene Größe in Bytes.

SharedArrayBuffer.prototype.slice()

Gibt einen neuen SharedArrayBuffer zurück, dessen Inhalt eine Kopie der Bytes dieses SharedArrayBuffer von begin (einschließlich) bis end (ausschließlich) ist. Ist begin oder end negativ, 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

js
const sab = new SharedArrayBuffer(1024);

Einen Ausschnitt aus dem SharedArrayBuffer erstellen

js
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

js
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