背景
WebGPU 类目前暴露了 destoryTexture(texture) 用于精细化的纹理生命周期管理,内部调用 WGPUTextureLike.getInstance(...).destroy() 释放显存:
// WebGPU.ts
destoryTexture(texture: TextureLike) {
WGPUTextureLike.getInstance(this.device, texture).destroy();
}
然而,没有对应的 destroyBuffer API 用于释放 GPUBuffer 资源。
问题
WGPUBuffer 和 WGPUBufferBinding 都注册了清理回调来释放底层 GPUBuffer:
// WGPUBuffer.ts
this.destroyCall(() => {
gpuBuffer?.destroy();
});
两者都使用 ChainMap(基于 WeakMap 构建)做缓存:
private static readonly map = new ChainMap<[GPUDevice, Buffer], WGPUBuffer>();
问题在于:WeakMap 的 GC 不保证触发 destroyCall 回调。当 JS 包装对象被垃圾回收时,底层的 gpuBuffer.destroy() 可能永远不会被调用,从而导致 GPU 显存泄漏。
这在长期运行、反复创建/销毁带 uniforms 的渲染对象的应用中(例如点云查看器、场景编辑器)尤为严重,buffer 持续累积导致显存稳步增长。
对比
| 资源类型 |
公开销毁 API |
缓存类型 |
是否可靠释放 |
| 纹理 Texture |
✅ destoryTexture |
ChainMap (WeakMap) |
✅ 是(显式调用) |
| 缓冲 Buffer |
❌ 无 |
ChainMap (WeakMap) |
❌ 否(依赖 GC) |
需求
在 WebGPU 类上新增一个公开方法,用于显式释放 buffer:
// 建议的 API
class WebGPU {
// 已有
destoryTexture(texture: TextureLike): void;
// 新增
destoryBuffer(bufferBinding: BufferBinding): void;
}
实现方式可参照 destoryTexture:
destoryBuffer(bufferBinding: BufferBinding) {
// 查找缓存的 WGPUBufferBinding 并销毁它
// (需要像 WGPUTextureLike 一样提供公开的 getInstance + destroy 路径)
}
当前临时方案
目前释放 buffer 的唯一途径是 WebGPU.destroy()(其内部仅 device = null),但这会销毁整个 device 上下文——对于增量式场景更新而言过于粗暴。
环境
@feng3d/webgpu:最新版
- 平台:Chrome 149 / WebGPU
相关建议:也可以考虑暴露 destroyAllBuffers(),或者让 WGPUBuffer/WGPUBufferBinding 公开它们的 destroy()(它们已经从 ReactiveObject 继承了 destroy())。
感谢这个优秀的库!🙏
背景
WebGPU类目前暴露了destoryTexture(texture)用于精细化的纹理生命周期管理,内部调用WGPUTextureLike.getInstance(...).destroy()释放显存:然而,没有对应的
destroyBufferAPI 用于释放GPUBuffer资源。问题
WGPUBuffer和WGPUBufferBinding都注册了清理回调来释放底层GPUBuffer:两者都使用
ChainMap(基于WeakMap构建)做缓存:问题在于:
WeakMap的 GC 不保证触发destroyCall回调。当 JS 包装对象被垃圾回收时,底层的gpuBuffer.destroy()可能永远不会被调用,从而导致 GPU 显存泄漏。这在长期运行、反复创建/销毁带 uniforms 的渲染对象的应用中(例如点云查看器、场景编辑器)尤为严重,buffer 持续累积导致显存稳步增长。
对比
destoryTexture需求
在
WebGPU类上新增一个公开方法,用于显式释放 buffer:实现方式可参照
destoryTexture:当前临时方案
目前释放 buffer 的唯一途径是
WebGPU.destroy()(其内部仅device = null),但这会销毁整个 device 上下文——对于增量式场景更新而言过于粗暴。环境
@feng3d/webgpu:最新版相关建议:也可以考虑暴露
destroyAllBuffers(),或者让WGPUBuffer/WGPUBufferBinding公开它们的destroy()(它们已经从ReactiveObject继承了destroy())。感谢这个优秀的库!🙏