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 rohen binären Datenpuffer darzustellen, ähnlich dem ArrayBuffer-Objekt, jedoch so, dass es möglich ist, Ansichten auf gemeinsam genutzten Speicher zu erstellen. Ein SharedArrayBuffer ist kein Transferable Object, im Gegensatz zu einem ArrayBuffer, der übertragbar ist.
Beschreibung
Um Speicher mithilfe von SharedArrayBuffer-Objekten von einem Agent im Cluster zu einem anderen zu teilen (ein Agent ist entweder das Hauptprogramm der Webseite oder einer ihrer Webworker), wird postMessage und strukturiertes Klonen verwendet.
Der Algorithmus für strukturiertes Klonen akzeptiert SharedArrayBuffer-Objekte und Typarrays, die auf SharedArrayBuffer-Objekte abgebildet sind. In beiden Fällen wird das SharedArrayBuffer-Objekt an den Empfänger übermittelt, was zu einem neuen, privaten SharedArrayBuffer-Objekt im empfangenden Agent führt (genau wie bei ArrayBuffer). Der gemeinsam genutzte Datenblock, auf den die beiden SharedArrayBuffer-Objekte verweisen, ist jedoch derselbe Datenblock, und ein Nebeneffekt auf den Block in einem Agent wird schließlich im anderen Agent sichtbar.
const sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
Gemeinsam genutzter Speicher kann gleichzeitig in Workern oder dem Hauptthread erstellt und aktualisiert werden. Je nach System (CPU, Betriebssystem, Browser) kann es eine Weile dauern, bis die Änderung in allen Kontexten propagiert wird. Um dies zu synchronisieren, sind atomare Operationen erforderlich.
SharedArrayBuffer-Objekte werden von einigen Web-APIs verwendet, wie zum Beispiel:
Sicherheitsanforderungen
Gemeinsam genutzter Speicher und hochauflösende Timer wurden Anfang 2018 effektiv deaktiviert im Lichte von Spectre. Im Jahr 2020 wurde ein neuer, sicherer Ansatz standardisiert, um gemeinsamen Speicher wieder zu ermöglichen.
Um gemeinsam genutzten Speicher zu verwenden, muss Ihr Dokument in einem sicheren Kontext sein und über Ursprünge isoliert sein. Sie können die Eigenschaften Window.crossOriginIsolated und WorkerGlobalScope.crossOriginIsolated verwenden, um zu überprüfen, ob das Dokument über Ursprünge 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 über Ursprünge isoliert, wirft postMessage() für SharedArrayBuffer-Objekte nicht länger Ausnahmen, und gemeinsam genutzter Speicher zwischen Threads ist daher verfügbar.
Verfügbarkeit von APIs
Je nachdem, 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, es sei denn, die beiden oben erwähnten Header sind gesetzt, für die Kompatibilität mit Web-Inhalten. Es besteht die Hoffnung, dass diese Einschränkung in Zukunft aufgehoben werden kann.WebAssembly.Memorykann dennoch verwendet werden, um eine Instanz zu erhalten.- Sofern die beiden oben genannten Header nicht gesetzt sind, werfen die verschiedenen
postMessage()-APIs fürSharedArrayBuffer-Objekte Ausnahmen. Wenn sie jedoch gesetzt sind, funktionierenpostMessage()aufWindow-Objekten und dedizierten Workern und ermöglichen die Speicherfreigabe.
WebAssembly gemeinsamer 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 Instruktionen. 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 Instruktionen ebenfalls bedingungslos erlaubt.
Wachstum von SharedArrayBuffers
SharedArrayBuffer-Objekte können durch Einschließen der maxByteLength-Option beim Aufruf des SharedArrayBuffer()-Konstruktors wachstumsfähig gemacht werden. Sie können überprüfen, 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 Wachstum von SharedArrayBuffers effizienter — andernfalls müssen Sie eine Kopie des Puffers mit einer neuen Größe erstellen. Es bringt auch die JavaScript-Parität mit WebAssembly in dieser Hinsicht (Wasm-Speicher kann mit WebAssembly.Memory.prototype.grow() resized werden).
Aus Sicherheitsgründen können SharedArrayBuffers nicht in der Größe reduziert werden, sondern nur wachsen.
Konstruktor
-
Erstellt ein neues
SharedArrayBuffer-Objekt.
Statische Eigenschaften
-
Gibt den Konstruktor zurück, der zur Konstruktion von Rückgabewerten von
SharedArrayBuffer-Methoden verwendet wird.
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 erstellt wird und kann nur geändert werden, wenn der
SharedArrayBufferwachstumsfähig ist, unter Verwendung derSharedArrayBuffer.prototype.grow()-Methode. -
Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für
SharedArrayBuffer-Instanzen ist der Initialwert derSharedArrayBuffer-Konstruktor. -
Schreibgeschützt. Gibt
truezurück, wenn derSharedArrayBufferwachsen kann, oderfalse, wenn nicht. -
Die schreibgeschützte maximale Länge, in Bytes, auf die der
SharedArrayBufferwachsen kann. Diese wird bei der Erstellung des Arrays festgelegt 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.
Instanz-Methoden
-
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. Wenn entwederbeginoderendnegativ ist, bezieht es sich auf einen Index vom Ende des Arrays, im Gegensatz zum Anfang.
Beispiele
Beachten Sie, dass diese Beispiele nicht direkt aus der Konsole oder einer beliebigen Webseite ausgeführt werden können, da SharedArrayBuffer nicht definiert ist, es sei denn, seine Sicherheitsanforderungen sind erfüllt.
Erstellen eines neuen SharedArrayBuffer
const sab = new SharedArrayBuffer(1024);
Slicing 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- JavaScript typisierte Arrays Leitfaden
- Web Worker
- Gemeinsamer Speicher – ein kurzes Tutorial im TC39 ecmascript-sharedmem Vorschlag
- Ein Vorgeschmack auf 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)