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 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.

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

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);
}

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.Memory kann weiterhin verwendet werden, um eine Instanz zu erhalten.
  • Sofern die beiden erwähnten Header nicht gesetzt sind, werfen die verschiedenen postMessage()-APIs für SharedArrayBuffer-Objekte eine Ausnahme. Sind sie gesetzt, funktionieren postMessage() bei Window-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

SharedArrayBuffer()

Erzeugt ein neues SharedArrayBuffer-Objekt.

Statische Eigenschaften

SharedArrayBuffer[Symbol.species]

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.

SharedArrayBuffer.prototype.byteLength

Die Größe des Arrays in Bytes. Diese wird festgelegt, wenn das Array erstellt wird und kann nur geändert werden, wenn der SharedArrayBuffer mit der SharedArrayBuffer.prototype.grow()-Methode wachstumsfähig ist.

SharedArrayBuffer.prototype.constructor

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

SharedArrayBuffer.prototype.growable

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

SharedArrayBuffer.prototype.maxByteLength

Die schreibgeschützte maximale Länge in Bytes, auf die der SharedArrayBuffer vergrößert werden kann. Diese wird festgelegt, wenn das Array erstellt wird und kann nicht geändert werden.

SharedArrayBuffer.prototype[Symbol.toStringTag]

Der anfängliche Wert der [Symbol.toStringTag]-Eigenschaft ist der String "SharedArrayBuffer". Diese Eigenschaft wird in Object.prototype.toString() verwendet.

Instanzmethoden

SharedArrayBuffer.prototype.grow()

Erhöht 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, inklusive, bis end, exklusiv ist. Wenn begin oder end negativ sind, bezieht es sich auf einen Index vom Ende des Arrays, im Gegensatz zum Anfang.

Beispiele

Erstellen eines neuen SharedArrayBuffer

js
const sab = new SharedArrayBuffer(1024);

Ausschneiden des SharedArrayBuffer

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

Specification
ECMAScript® 2026 Language Specification
# sec-sharedarraybuffer-objects

Browser-Kompatibilität

Siehe auch