Start · Sprachen · JavaScript · Referenz · GPUDevice.destroy()

GPUDevice.destroy()

Methode

Zerstört ein <code>GPUDevice</code>, gibt seine GPU-Ressourcen frei und verhindert alle weiteren Operationen darauf.

seit JavaScript WebGPU – Chrome/Edge 113+, Safari 26+, Firefox 141 Kategorie: webapi

Signatur

GPUDevice.prototype.destroy()

Beschreibung

destroy() beendet ein logisches WebGPU-Gerät endgültig. Alle Ressourcen, die über dieses Gerät erzeugt wurden (Buffer, Texturen, Pipelines, Bind Groups usw.), werden damit ungültig. Laufende Mappings von Buffern werden abgebrochen, sodass ausstehende GPUBuffer.mapAsync()-Promises abgelehnt werden.

Vor dem Zerstören werden alle bereits über device.queue.submit() übermittelten Befehle noch fertig abgearbeitet. Danach wird das Promise GPUDevice.lost mit einem GPUDeviceLostInfo erfüllt, dessen reason den Wert "destroyed" hat. So kannst du einen gewollten Abbau von einem unerwarteten Geräteverlust (z. B. Treiberabsturz) unterscheiden.

Einsetzen solltest du die Methode, wenn eine GPU-Anwendung oder -Komponente nicht mehr gebraucht wird, z. B. beim Unmount einer Komponente in einer Single-Page-Application, beim Schließen eines Editors oder in Tests. So gibst du GPU-Speicher sofort frei, statt auf die Garbage Collection zu warten. Ein zerstörtes Gerät lässt sich nicht reaktivieren; für einen Neustart forderst du mit adapter.requestDevice() ein neues Gerät an.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Das Ergebnis siehst du am Promise device.lost, das mit reason: "destroyed" erfüllt wird.

Beispiele

Gerät anfordern und gezielt zerstören

const init = async () => {
  if (!navigator.gpu) throw new Error('WebGPU wird nicht unterstützt');
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  // Auf Geräteverlust reagieren
  device.lost.then((info) => {
    console.log(`Gerät verloren: ${info.reason}`);
  });

  // ... Rendering / Compute ...

  device.destroy();
};

init();
Gerät verloren: destroyed

Gewollten Abbau von unerwartetem Verlust unterscheiden

const createDevice = async () => {
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  device.lost.then(async (info) => {
    if (info.reason === 'destroyed') {
      console.log('Absichtlich zerstört – kein Neustart.');
      return;
    }
    console.warn('Unerwarteter Verlust:', info.message);
    await createDevice(); // neu initialisieren
  });

  return device;
};

const device = await createDevice();
device.destroy();
Absichtlich zerstört – kein Neustart.

Aufräumen beim Entfernen einer Komponente

class GpuView {
  async init(canvas) {
    const adapter = await navigator.gpu.requestAdapter();
    this.device = await adapter.requestDevice();
    this.context = canvas.getContext('webgpu');
    this.context.configure({
      device: this.device,
      format: navigator.gpu.getPreferredCanvasFormat(),
    });
  }

  dispose() {
    cancelAnimationFrame(this.frameId);
    this.context?.unconfigure();
    this.device?.destroy(); // GPU-Speicher sofort freigeben
    this.device = null;
  }
}

const view = new GpuView();
await view.init(document.querySelector('canvas'));
// später, z. B. beim Seitenwechsel:
view.dispose();

Ausstehendes mapAsync wird abgelehnt

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const buffer = device.createBuffer({
  size: 16,
  usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
});

const pending = buffer.mapAsync(GPUMapMode.READ);
device.destroy();

try {
  await pending;
} catch (err) {
  console.log(err.name);
}
AbortError

// Wichtig · Fallstricke

  • Nicht umkehrbar: Nach destroy() ist das Gerät dauerhaft unbrauchbar. Ein erneuter Aufruf ist erlaubt, bewirkt aber nichts. Für einen Neustart brauchst du ein neues Gerät über adapter.requestDevice(). Ein Adapter, der schon ein Gerät geliefert hat, gilt je nach Implementierung als „verbraucht“. Fordere dann auch einen neuen Adapter an.
  • Keine Ausnahmen: Aufrufe auf einem zerstörten Gerät (z. B. createBuffer()) werfen meist keinen Fehler, sondern erzeugen ungültige Objekte oder werden stillschweigend ignoriert. Prüfe den Zustand über device.lost, nicht über try/catch.
  • Übermittelte Arbeit läuft noch fertig: Befehle, die vor destroy() an die Queue übergeben wurden, werden noch ausgeführt. Ausstehende mapAsync()-Promises werden dagegen mit einem AbortError abgelehnt.
  • Einzelne Ressourcen: Wenn du nur einzelne Buffer oder Texturen freigeben willst, nutze GPUBuffer.destroy() bzw. GPUTexture.destroy(), statt das ganze Gerät zu zerstören.
  • Kompatibilität: WebGPU steht nur in sicheren Kontexten (HTTPS) zur Verfügung und wird noch nicht überall unterstützt. Prüfe vorher, ob navigator.gpu vorhanden ist, und sieh einen Ersatzweg vor (z. B. WebGL).