#17281·openlayers

WebGL 渲染器: 条件性缓冲区删除可避免崩溃,但在删除辅助程序后会留下过时的引用

作者: ju-piet创建于 2026年1月8日更新于 2026年7月16日
标签bug

描述

此问题与以下 OpenLayers 问题报告有关(并基于该问题报告): https://GitHub.com/openlayers/openlayers/issues/16649 我们遇到了同样的 WebGL 生命周期问题,其中 WebGL 的 helper 在所有渲染器拥有的 GPU 资源都被正确释放之前就被移除。

背景

当删除或释放 WebGL 层时,会调用 removeHelper(),WebGL 上下文/助手可能已经未定义,而内部缓冲区仍然由渲染器引用。

这会导致尝试通过助手删除缓冲区时发生崩溃。

当前的工作方法

为了避免崩溃,我们在删除缓冲区时添加了一个 防护检查

typescript
for (const buffer of typeBuffers) {   
	if (buffer) {     
	// Helper 可能已经未定义。     
// 请参阅 https://GitHub.com/openlayers/openlayers/issues/16649     
	this.helper?.deleteBuffer(buffer);   
	} 
}

这可避免在助手丢失时出现运行时错误。

仍然存在的问题:过时的引用

虽然这可避免崩溃,但 底层引用问题仍然存在

  • helper 已经未定义时,WebGL 缓冲区无法在 GPU 端删除。
  • 渲染器仍然在内部结构(typeBuffers、缓存等)中保留着对这些 WebGLBuffer 对象的引用。
  • 这些过时的引用可能会导致以下情况:
  • 尝试重复删除,
  • 在重建期间重新使用,
  • 或导致内存泄漏和 WebGL 行为未定义。

换句话说,此修复可避免异常,但无法完全清理渲染器状态。

为什么这会产生问题

从应用程序的角度来看,如果不想在不风险的情况下释放 WebGL 层,就无法确保:

  • 清理不完整(内存泄漏),
  • CPU 端仍然保留着引用,
  • 或在删除助手后渲染器状态不一致。

这也使得实现安全的生命周期管理(例如动态添加/删除层、样式重建、React 卸载)变得困难。

内容来源: openlayers/openlayers