Cesium1.95中如何高效管理 1500 个高频实体
一、建议:
- 不要频繁创建/销毁,而是复用对象;
- 使用 CallbackProperty更新位置而不是删了重建;
- 对大量 Billboard / Polyline / Label,优先使用对应的 *Collection,然后批量更新;
- 最后通过 removeAll()+ remove()批量移除,而不是逐个销毁;
二、正确的性能优化手段是:
优化方向 | 措施 | 是否推荐 |
---|---|---|
高频实体管理 | 使用 | ✅ 强烈推荐 |
批量移除 | 使用 | ✅ 推荐 |
移除渲染对象 | 从 | ✅ 必须 |
避免内存泄漏 | 移除后解除 JS 引用(如设为 | ✅ 推荐 |
三、为什么销毁后内存仍泄漏?——最常见原因排行榜
原因 | 是否常见 | 解决方案 |
---|---|---|
JavaScript 对象仍被变量 / 数组 / 缓存引用 | ⭐⭐⭐⭐⭐ | 手动置 null 或清空数组/对象 |
事件监听器未移除(闭包持有引用) | ⭐⭐⭐ | 移除事件,避免闭包长期持有 |
定时器 / 动画帧未清除 | ⭐⭐⭐ | 销毁前 |
尝试调用不存在的 API | ⭐⭐ | 只需 |
第三方库 / 自己的代码缓存了 Entity / Primitive 对象 | ⭐⭐⭐⭐ | 检查缓存逻辑并清理 |
GC 延迟,对象尚未被回收(假性泄漏) | ⭐⭐ | 观察一段时间,或强制触发 GC(Chrome 可手动触发) |
四、你应该怎么做?—— 排查与优化 checklist
步骤 | 操作 | 是否完成 |
---|---|---|
1 | 调用 | ✅ 你已完成 |
2 | 调用 | ✅ 你已完成 |
3 | 将相关对象引用设为 | ⚠️ 请检查 |
4 | 检查是否有全局变量 / 数组 / 缓存仍然持有这些对象 | ⚠️ 重点排查 |
5 | 移除所有事件监听器(如 entity.click) | ⚠️ 检查绑定逻辑 |
6 | 清除定时器 / requestAnimationFrame | ⚠️ 检查循环逻辑 |
7 | 用 Chrome DevTools Memory 工具做 Heap Snapshot 对比分析 | ⚠️ 强烈推荐 |
五、如何进一步诊断内存泄漏?
✅ 方法 1:Chrome DevTools → Memory 工具
推荐操作:
- 打开 Chrome 开发者工具 → Memory 标签
- 使用 Heap Snapshot 功能:
- 在销毁前拍一个快照(Snapshot 1)
- 执行你的销毁代码(removeAll()等)
- 等待几秒后,再拍一个快照(Snapshot 2)
- 使用 Comparison(对比) 查看:
- 哪些 Cesium.Entity/ PolylineCollection等对象数量没有下降
- 谁仍然持有这些对象的引用(Retainers)
- 使用 Allocation instrumentation on timeline:
- 可以观察内存分配随时间的变化,找到持续增长的对象类型。
步骤 | 操作 | 目的 |
---|---|---|
1️⃣ | 打开 Chrome DevTools → Memory | 进入内存分析工具 |
2️⃣ | 选择 Heap Snapshot → 点击 Take snapshot | 拍摄销毁前的内存状态(如:创建了 1500 个 Entity) |
3️⃣ | 执行你的销毁代码(如 | 移除 Cesium 对象 |
4️⃣ | 再次进入 Memory → Heap Snapshot → Take snapshot | 拍摄销毁后的内存状态 |
5️⃣ | 在 Heap Snapshot 面板,选择 Comparison 视图 | 切换为对比模式 |
6️⃣ | 在下拉菜单中: | 查看哪些对象仍然存在(疑似泄漏) |
7️⃣ | 查看 Objects 数量异常的对象(比如 Cesium.Entity 仍有 1000 个) | 定位可能泄漏的类型 |
8️⃣ | 点击具体对象/类型 → 查看 Retainers 引用链 | 找出谁(变量/闭包/缓存)仍然引用着它 |