Sorry to bother again, though I think I found another WebGPU memory leak
Thanks to fixes by Evgeni, I was able to get my WebGPU project in a state with no memory leaks. Now I’m enabling game features one by one to see if any of them introduce leaks. Indeed, after enabling only bullet trails (using GreasedLines), it seems that a new leak was found.
I’m creating and disposing several GreasedLines a second, and they are all sharing the same StandardMaterial. The code looks something like:
// Base `GreasedLine` only created once
const baseLine = BABYLON.CreateGreasedLine(/* options */);
const baseMaterial = baseLine.material; // `StandardMaterial` by default
// For every fired bullet, create a new `GreasedLine` and use the shared material:
const lineInstance = new GreasedLineMesh('', scene, { points: [/* points */] });
// By default, `lineInstance.material === null`, so the leak is not from generating new materials.
lineInstance.material = baseMaterial; // share material
// After a few seconds, every bullet's `GreasedLine` is disposed:
lineInstance.dispose();
In Chrome DevTools, I took a Heap snapshot, waited 2 minutes, then collected a 2nd Heap snapshot, which grew by ~7 MB. When comparing both snapshots, by far the most common object generated (out of ~26,500) that wasn’t being garbage collected was in WebGPUCacheBindGroups.
I also tested this on WebGL2, and there seemed to be no leak
, so this only seems to affect WebGPU.
Please see a video here demonstrating the leak on WebGPU:
Link to project using WebGPU (has leak)
: Document
Link to project using WebGL (no leak)
: Document
Claude
I asked Claude:
@workspace Is there a leak with
WebGPUBindGroupCacheNode? I’m creating a lot ofGreasedLines (they all share the same StandardMaterial). However, Chrome DevTools is showing a memory leak of a few MB per minute, and it’s indicating thatWebGPUBindGroupCacheNodecould be the culprit.
Response:
Looking at webgpuCacheBindGroups.ts, yes — there is a real leak risk with WebGPUBindGroupCacheNode.
Why it leaks with many GreasedLine meshes:
The cache is a trie keyed on:
Buffer uniqueIds (from drawContext.buffers)
Sampler hash codes
Texture uniqueIds
// New node created for every unique buffer/texture id combination let nextNode = new WebGPUBindGroupCacheNode(); node.values[uboId] = nextNode;_Cache is a static, global trie that grows indefinitely:
private static _Cache: WebGPUBindGroupCacheNode = new WebGPUBindGroupCacheNode();Each GreasedLineMesh has its own WebGPUDrawContext with unique buffer IDs (for
grl_offsets,grl_widths,grl_colorPointers, etc.). When you dispose a mesh, its draw context is released, but the trie nodes keyed on those buffer IDs are never pruned — they remain in_Cacheforever with danglingGPUBindGroup[]references.Why it’s worse for GreasedLine specifically:
Each
[GreasedLineMesh](packages/dev/core/src/Meshes/GreasedLine/greasedLineMesh.ts)registers several custom vertex buffersgrl_offsets,grl_widths,grl_colorPointers,grl_previousAndSide,grl_nextAndCounters) — all with unique IDs — so each mesh adds significantly more trie branches than a standard mesh.Workarounds available to you:
1. Periodically reset the cache (most aggressive, causes a one-frame rebuild):
import { WebGPUCacheBindGroups } from "@babylonjs/core/Engines/WebGPU/webgpuCacheBindGroups"; // Call after batches of dispose() calls WebGPUCacheBindGroups.ResetCache();2. Disable the bind group cache entirely (simpler but slightly slower rendering):
const engine = scene.getEngine() as WebGPUEngine; engine.disableCacheBindGroups = true;3. Reuse meshes instead of creating/disposing — use setPoints to update existing lines rather than creating new ones, so buffer IDs stay stable and the trie doesn’t grow:
// Instead of dispose + CreateGreasedLine: existingLine.setPoints(newPoints);Option 3 is the best long-term fix as it avoids both the leak and any cache-reset frame hitches. Option 1 is a good safety net if you must create/dispose frequently.
I’m unsure if Claude is on the right path here or if any of the workarounds it suggested are good ideas.
I would greatly appreciate any help here
Thank you!!