[
【投稿赢 iPhone 17】「我的第一个开源项目」故事征集:用代码换C位出道!
10w+人浏览
1.6k人参与
](https://activity.csdn.net/writing?id=10899)

网罗开发 (小红书、快手、视频号同名)
大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
上一章我们聊了 Vue + GeoScene 项目中常见的内存泄漏原因,以及如何正确销毁地图实例。但很多时候,光“猜”是不够的——我要怎么证明泄漏确实存在?又要如何判断是哪一块对象没被释放?
这就是本篇的重点:
用 Chrome DevTools 进行深度内存分析,定位 WebGL + Vue 项目中的真实泄漏点。
这篇文章适合你,如果你:
准备好探索内存世界了吗?我们开始。
WebGL 绘制地图时会创建:
这些不是 JS 对象本身,而是浏览器 GPU 层级的资源。
只靠 JS 引用释放并不一定能马上回收。
Vue 的响应式系统会:
一旦对地图对象、图层对象、canvas 节点有闭包引用,GC(垃圾回收)就无法回收。
GeoScene 或地图本身会绑定:
如果你没有卸载,浏览器会一直 hold 住这些对象。
所以调试 WebGL 内存问题,必须借助 Chrome DevTools。
打开 DevTools:
Chrome → 右上角菜单 → 更多工具 → 开发者工具
切换到:
这两个面板是分析 WebGL 内存问题的主战场。
你会看到一条类似这样的曲线:
Memory: 120MB → 150MB → 200MB → 260MB → ...
如果切换页面后内存没有下降,那么:
这是第一层诊断。
对象快照可以帮你直接找到泄漏来源。
然后对比两个快照。
重点关注:
| 类型 | 是否危险 | 原因 |
|---|---|---|
HTMLCanvasElement | 高 | Canvas 节点未移除,会导致 WebGL 上下文泄漏 |
WebGLRenderingContext | 高 | 未释放 WebGL 资源 |
EventListener | 中高 | window 监听器未解绑 |
GeoSceneMap / MapView | 高 | 地图对象未销毁 |
Proxy、Object | 中 | Vue 响应式和闭包引用 |
在快照中:
Detached HTMLDivElement如果看到这样的内容:
Detached HTMLDivElement
↳ GeoSceneMap
↳ LayerManager
↳ window resize listener
不用怀疑 —— 你地图实例被监听器“锁”住了,所以没有被释放。
这是确定某段操作是否“疯狂创建对象”的最强方式。
你会看到:
如果你看到大量:
WebGLBufferWebGLTextureArrayFloat32ArrayProxy在不停涨,那就是你的图层或渲染器在不断创造新资源但没销毁。
例子:
5000 个 WebGLBuffer,在 10 秒内创建 → 内存疯涨 → 必爆!
Chrome 提供一个隐藏能力:
Chrome 会显示你当前页面创建了几个 WebGL context。
打开控制台输入:
performance.memory
也可以查看:
document.querySelectorAll("canvas")
如果你切换 5 次地图页,但 canvas 从 1 个变成 5 个,说明:
地图容器没有被销毁
WebGL 上下文泄漏
内存不会下降,迟早崩
Vue 和地图常见的问题是事件监听器没有移除。
打开 Chrome:
Elements → Event Listeners
然后展开:
如果你看到:
resize → 5 个监听器 →
GeoSceneMap instance
说明你页面切换 5 次,注册了 5 次 resize 事件,没有卸载。
这是许多 WebGL 框架内存泄漏的元凶!
加一段打印代码,让你确认 Vue 销毁逻辑确实执行:
onBeforeUnmount(() => {
console.log("组件销毁开始");
console.trace();
});
如果切换页面没有触发这个打印 ——
你把地图组件放在 KeepAlive 里了,当然不会销毁。
假设你遇到的场景:
下面是一段可运行的 Demo,包含问题、定位和修复。
onMounted(() => {
map = new GeoSceneMap({ ... });
window.addEventListener('resize', () => map.resize());
});
这个匿名函数监听器无法移除,会导致 WebGL 上下文永远泄漏。
DevTools 中你会看到:
let map: any = null;
function handleResize() {
map?.resize();
}
onMounted(() => {
map = new GeoSceneMap({...});
window.addEventListener('resize', handleResize);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize);
map?.destroy();
map = null;
});
再用 DevTools Memory 查看快照,引用链会消失,map 对象能正确被 GC。
只要这份 Checklist 过了一遍,你的内存泄漏基本跑不掉。
内存优化不是猜出来的,是查出来的。
借助 Chrome DevTools:
掌握这套方法,你不仅能搞定 GeoScene 内存泄漏,所有 WebGL、地图、可视化项目的性能瓶颈,你都能快速定位。