前言
前端应用的内存泄漏,指不再使用的内存未被释放,导致页面占用持续增长。轻则引发卡顿、加载缓慢,重则导致浏览器崩溃。尤其在单页应用(SPA)中,路由切换频繁但内存不回收,问题会被无限放大。比如用户长时间使用某后台管理系统,可能出现操作响应延迟,甚至需要强制刷新才能恢复,这很可能是内存泄漏在'作祟'。
常见内存泄漏场景
- 意外的全局变量:未声明的变量(如
a = 10而非let a = 10)会挂载到window上,页面不刷新就不会释放。 - 闭包滥用:闭包会保留对外部作用域的引用,若长期持有 DOM 或大型对象,会导致内存无法回收(如未清理的事件监听回调)。
- 未清理的 DOM 引用:删除 DOM 节点后,仍保留其引用(如
let el = document.getElementById('test'),删除el对应的 DOM 后未置el = null)。 - 定时器 / 事件监听未销毁:
setInterval未用clearInterval清除、addEventListener未用removeEventListener解绑,尤其在组件挂载 / 卸载时容易遗漏。 - 第三方库 / 插件残留:部分第三方库(如图表库、播放器)使用后未调用销毁方法,导致内部资源无法释放。
- 数组 / 对象无限增长:全局缓存对象未设置过期机制,或数组持续 push 数据但未清理无效项。
核心工具:浏览器开发者工具 (Chrome DevTools)
复现泄露场景
首先需要稳定复现泄露行为,比如:
- 路由切换(SPA 中反复切换 A→B→A→B);
- 点击按钮触发某操作(如打开弹窗后关闭);
- 长时间滚动或轮询请求数据。
开启 Memory 面板
打开 Chrome 开发者工具,勾选面板顶部的「Memory」选项(同时可保留默认的「CPU」「Network」)。点击左上角的「录制」按钮(圆形红点),然后执行复现步骤(如切换路由 5 次)。执行完成后点击「停止」,等待面板生成报告。

关键观察点: 报告中 [Memory] 曲线若持续上升且不回落(即使操作停止后,内存仍未下降),则大概率存在泄露。若曲线在操作后能回落至初始水平,说明内存已正常回收,无泄露。
定位泄露对象
Performance 面板确认泄露后,用 Memory 面板进一步定位'哪些对象未被回收'。Memory 面板支持 3 种快照类型,按需选择:
- Heap snapshot(堆快照):捕获当前内存中所有对象的快照,可对比不同快照的差异,适合定位未回收的对象;
- Allocation instrumentation on timeline(时间线分配记录):实时记录内存分配过程,适合观察某操作期间的内存分配细节;
- Allocation sampling(分配采样):低开销的内存采样,适合快速排查大面积泄露,无需精确到单个对象。
堆快照对比操作
- 打开 DevTools → 切换到「Memory」面板;
- 选择「Heap snapshot」,点击「Take snapshot」拍摄初始快照(记为快照 1,此时未执行任何操作);
- 执行一次泄露复现步骤(如切换一次路由);
- 再次点击「Take snapshot」拍摄快照 2;















