Start · Sprachen · JavaScript · Referenz · new SharedArrayBuffer()

new SharedArrayBuffer()

Methode

Der Konstruktor <code>SharedArrayBuffer()</code> erzeugt einen Binärpuffer fester (oder begrenzt wachsender) Länge, den sich mehrere Threads bzw. Worker teilen können.

seit JavaScript ES2017 (maxByteLength-Option: ES2024) Kategorie: method-property

Signatur

new SharedArrayBuffer(length, options)

Beschreibung

Mit new SharedArrayBuffer(length) legst du einen zusammenhängenden Speicherbereich von length Bytes an, der mit Nullen gefüllt ist. Anders als beim ArrayBuffer wird der Speicher bei der Übergabe per postMessage() an einen Worker nicht kopiert und nicht übertragen. Beide Seiten greifen auf denselben physischen Speicher zu.

Direkt lesen oder schreiben kannst du den Puffer nicht. Dafür brauchst du eine Sicht darauf, also ein typisiertes Array wie Int32Array oder eine DataView. Wenn mehrere Threads gleichzeitig zugreifen, solltest du Atomics verwenden (z. B. Atomics.add(), Atomics.wait(), Atomics.notify()). Nur so bleiben Lese- und Schreibvorgänge atomar und in der richtigen Reihenfolge.

Seit ES2024 kannst du mit der Option maxByteLength einen wachstumsfähigen Puffer anlegen. Er lässt sich mit grow() vergrößern, aber nie verkleinern. Typische Einsatzfälle sind WebAssembly-Threads, rechenintensive Parallelverarbeitung (Bild-/Audioverarbeitung) und Ringpuffer zwischen dem Haupt-Thread und einem AudioWorklet.

Parameter

Name Typ Default Beschreibung
$length Pflicht number Größe des Puffers in Bytes. Nicht ganzzahlige Werte werden abgeschnitten. Negative oder zu große Werte lösen einen RangeError aus.
$options object Optionales Objekt. Unterstützt wird maxByteLength (number): die maximale Größe, auf die der Puffer mit grow() wachsen darf. Der Wert muss ≥ length sein.

Rückgabewert

Typ
SharedArrayBuffer
Beschreibung
Ein neues SharedArrayBuffer-Objekt der angegebenen Größe, mit Nullen initialisiert. Mit maxByteLength ist es wachstumsfähig (growable === true).

Beispiele

Puffer anlegen und über ein typisiertes Array nutzen

const sab = new SharedArrayBuffer(16); // 16 Bytes
const view = new Int32Array(sab);      // 4 × 32-Bit-Integer

view[0] = 42;
console.log(sab.byteLength, view.length, view[0]);
16 4 42

Gemeinsamer Zähler zwischen Haupt-Thread und Worker

// main.js
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const counter = new Int32Array(sab);

const worker = new Worker('worker.js');
worker.postMessage(sab); // kein Kopieren – gleicher Speicher

worker.onmessage = () => {
  console.log('Zähler:', Atomics.load(counter, 0));
};

// worker.js
self.onmessage = ({ data }) => {
  const counter = new Int32Array(data);
  for (let i = 0; i < 1000; i++) Atomics.add(counter, 0, 1);
  self.postMessage('fertig');
};
Zähler: 1000

Wachstumsfähiger Puffer (ES2024)

const sab = new SharedArrayBuffer(8, { maxByteLength: 64 });
console.log(sab.growable, sab.byteLength, sab.maxByteLength);

sab.grow(32);
console.log(sab.byteLength);

try {
  sab.grow(16); // Verkleinern ist nicht erlaubt
} catch (e) {
  console.log(e.name);
}
true 8 64 32 RangeError

Verfügbarkeit prüfen (Cross-Origin-Isolation)

if (typeof SharedArrayBuffer === 'undefined' || !globalThis.crossOriginIsolated) {
  console.warn('SharedArrayBuffer nicht verfügbar – COOP/COEP-Header fehlen?');
} else {
  const sab = new SharedArrayBuffer(1024);
  console.log('OK:', sab.byteLength);
}
OK: 1024

// Wichtig · Fallstricke

  • Sicherheit / Cross-Origin-Isolation: Wegen Spectre ist SharedArrayBuffer in Browsern nur in cross-origin-isolierten Kontexten verfügbar. Dafür muss die Seite die Header Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp (oder credentialless) senden. Ob das greift, prüfst du mit crossOriginIsolated. Außerdem ist ein sicherer Kontext (HTTPS) nötig.
  • Den Konstruktor musst du mit new aufrufen. SharedArrayBuffer(8) ohne new wirft einen TypeError.
  • Race Conditions: Normale Zugriffe über typisierte Arrays sind nicht synchronisiert. Für gemeinsam genutzte Zähler, Flags und Sperren brauchst du Atomics.
  • Atomics.wait() ist im Haupt-Thread von Browsern nicht erlaubt. Verwende dort Atomics.waitAsync().
  • Einen SharedArrayBuffer kannst du nicht in die Transfer-Liste von postMessage() aufnehmen. Er wird automatisch geteilt.
  • Einige APIs lehnen geteilten Speicher ab, etwa TextDecoder.decode() in manchen Browsern. Dann musst du vorher in einen ArrayBuffer kopieren.
  • In Node.js ist SharedArrayBuffer ohne Einschränkungen verfügbar (z. B. mit worker_threads). Die Option maxByteLength gibt es ab Chrome 111, Firefox 128, Safari 16.4 und Node.js 20.