Start · Sprachen · JavaScript · Referenz · SharedArrayBuffer.prototype.grow()

SharedArrayBuffer.prototype.grow()

Methode

Vergrößert einen wachstumsfähigen <code>SharedArrayBuffer</code> auf die angegebene Größe in Bytes. Verkleinern ist dabei nicht möglich.

seit JavaScript ES2024 Kategorie: method-property

Signatur

SharedArrayBuffer.prototype.grow(newLength)

Beschreibung

Mit grow() vergrößern Sie einen SharedArrayBuffer, ohne einen neuen Speicherbereich anzulegen und die Daten zu kopieren. Das geht nur, wenn der Puffer mit der Option maxByteLength erzeugt wurde, also wachstumsfähig ist: new SharedArrayBuffer(länge, { maxByteLength }). Ob das der Fall ist, sehen Sie an der Eigenschaft growable.

Die bisherigen Daten bleiben erhalten, und die neuen Bytes werden mit 0 gefüllt. Weil ein SharedArrayBuffer von mehreren Agenten (Hauptthread, Web Worker, Node.js-Worker-Threads) gleichzeitig benutzt wird, sehen alle Threads das Wachstum. Anders als bei ArrayBuffer.prototype.resize() kann ein geteilter Puffer nur wachsen, nie schrumpfen. Sonst könnten andere Threads auf Speicher zugreifen, der nicht mehr existiert.

Typisch ist die Methode bei Datenstrukturen, die zwischen Threads geteilt werden und über die Zeit wachsen, etwa Ringpuffer, Warteschlangen oder die Speicher-Erweiterung in WebAssembly-nahem Code. Typisierte Arrays, die ohne feste Länge („längenverfolgend“) auf dem Puffer erzeugt wurden, wachsen automatisch mit.

Parameter

Name Typ Default Beschreibung
$newLength Pflicht number Die neue Größe in Bytes. Sie muss mindestens so groß wie die aktuelle byteLength sein und darf maxByteLength nicht überschreiten.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Der Puffer wird direkt verändert.

Beispiele

Wachstumsfähigen Puffer anlegen und vergrößern

const sab = new SharedArrayBuffer(8, { maxByteLength: 64 });

console.log(sab.growable);      // true
console.log(sab.byteLength);    // 8

sab.grow(32);
console.log(sab.byteLength);    // 32
console.log(sab.maxByteLength); // 64
true 8 32 64

Längenverfolgendes Typed Array wächst mit

const sab = new SharedArrayBuffer(4, { maxByteLength: 16 });
const fixed = new Uint8Array(sab, 0, 4); // feste Länge
const tracking = new Uint8Array(sab);    // folgt der Puffergröße

tracking[0] = 42;
sab.grow(16);

console.log(fixed.length);    // 4
console.log(tracking.length); // 16
console.log(tracking[0], tracking[15]); // 42 0
4 16 42 0

Sicher wachsen mit Prüfung und Fehlerbehandlung

const ensureCapacity = (sab, needed) => {
  if (!sab.growable) {
    throw new TypeError('Puffer ist nicht wachstumsfähig');
  }
  if (needed <= sab.byteLength) return; // groß genug
  const target = Math.min(
    Math.max(needed, sab.byteLength * 2),
    sab.maxByteLength
  );
  if (target < needed) {
    throw new RangeError(`Maximum von ${sab.maxByteLength} Bytes erreicht`);
  }
  sab.grow(target);
};

const buffer = new SharedArrayBuffer(1024, { maxByteLength: 8192 });
ensureCapacity(buffer, 3000);
console.log(buffer.byteLength);

try {
  buffer.grow(100); // Verkleinern ist verboten
} catch (err) {
  console.log(err.name);
}
3000 RangeError

Wachstum für einen Worker sichtbar machen

// main.js
const sab = new SharedArrayBuffer(1024, { maxByteLength: 1024 * 1024 });
const worker = new Worker('worker.js');
worker.postMessage(sab);

setTimeout(() => {
  sab.grow(4096);
  worker.postMessage('grown');
}, 100);

// worker.js
let shared;
self.onmessage = ({ data }) => {
  if (data instanceof SharedArrayBuffer) shared = data;
  else console.log('Neue Größe im Worker:', shared.byteLength);
};
Neue Größe im Worker: 4096

// Wichtig · Fallstricke

  • TypeError: Kommt, wenn der Puffer ohne maxByteLength erzeugt wurde (growable === false).
  • RangeError: Kommt, wenn newLength größer als maxByteLength oder kleiner als die aktuelle byteLength ist. Ein SharedArrayBuffer kann nie schrumpfen.
  • Typisierte Arrays mit fester Länge wachsen nicht mit. Nur Ansichten ohne Längenangabe folgen der Puffergröße.
  • Das Wachstum selbst ist atomar. Wenn aber mehrere Threads gleichzeitig grow() aufrufen, kann ein Aufruf mit einem RangeError scheitern, weil ein anderer Thread den Puffer schon weiter vergrößert hat. Bei Bedarf sollten Sie das mit Atomics abstimmen.
  • Eine große maxByteLength kann Adressraum reservieren. Wählen Sie den Wert deshalb realistisch.
  • Kompatibilität: Die Methode ist Teil von ES2024 und läuft ab Chrome 111, Firefox 128, Safari 16.4 und Node.js 20. SharedArrayBuffer gibt es in Browsern nur in einem cross-origin isolated Kontext, also mit den Headern Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp. Hintergrund sind die Spectre-Schutzmaßnahmen.