一、建議:
- 不要頻繁創建/銷毀,而是復用對象;??
- ??使用 CallbackProperty更新位置而不是刪了重建;??
- ??對大量 Billboard / Polyline / Label,優先使用對應的 *Collection,然后批量更新;??
- ??最后通過 removeAll()+ remove()批量移除,而不是逐個銷毀;?
二、正確的性能優化手段是:
優化方向 | 措施 | 是否推薦 |
---|---|---|
??高頻實體管理?? | 使用? | ? 強烈推薦 |
??批量移除?? | 使用? | ? 推薦 |
??移除渲染對象?? | 從? | ? 必須 |
??避免內存泄漏?? | 移除后解除 JS 引用(如設為? | ? 推薦 |
三、為什么銷毀后內存仍泄漏?——最常見原因排行榜
原因 | 是否常見 | 解決方案 |
---|---|---|
??JavaScript 對象仍被變量 / 數組 / 緩存引用?? | ????? | 手動置 null 或清空數組/對象 |
??事件監聽器未移除(閉包持有引用)?? | ??? | 移除事件,避免閉包長期持有 |
??定時器 / 動畫幀未清除?? | ??? | 銷毀前? |
??誤以為 Cesium 有? | ?? | 只需? |
??第三方庫 / 自己的代碼緩存了 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?? 引用鏈 | 找出誰(變量/閉包/緩存)仍然引用著它 |