DirectSurface UIDirectSurface UI
开始使用
文档/性能与调试

内存泄露检查清单

复杂 Canvas 应用关闭页面后,内存不下降通常不是 canvas 绘制本身的问题,而是对象仍被引用。

页面关闭时必须释放

  • 页面根 RenderObject。
  • 页面 controller。
  • 页面级 AppContext。
  • 页面级 CommandScope。
  • Popup、Modal、Window。
  • 事件订阅。
  • setTimeout / setInterval。
  • Image 加载回调。
  • 大数组、大文本、大文档模型。
  • 业务缓存。

dispose 规则

组件持有可释放对象时,必须在 dispose() 中释放。

dispose():
  dispose owned controller
  remove event subscriptions
  clear timers
  close popups
  call parent dispose

如果对象由外部传入,组件要明确是否拥有它。只有 ownsController 为 true 时才由组件释放 controller。

资源缓存

资源缓存应尽量挂到文档上下文或页面上下文,不要默认全局缓存。

适合页面级缓存:

  • 当前文档图片。
  • 当前文档条码计划。
  • 当前页面查询结果。
  • 当前页面临时对象。

适合全局缓存:

  • 字体。
  • 主题常量。
  • 小型纯函数结果,并且有上限。

常见泄露来源

  • PopupManager 仍持有关闭页面的 popup。
  • Window owner/owned 关系没有解除。
  • 全局事件监听没有 remove。
  • Image.onload 闭包引用组件。
  • 文档缓存挂在模块级 Map。
  • AppContext 中放了大对象且没有 dispose。

验证流程

  1. 打开页面。
  2. 加载大数据。
  3. 关闭页面。
  4. 手动触发应用实例 dispose。
  5. 生成 heap snapshot。
  6. 搜索页面类名、文档 id、大数组关键字段。
  7. 查看 retainers,定位谁还持有对象。