单页应用路由切换内存泄漏源于组件、状态、监听器或定时器未释放;检测分三步:任务管理器初筛、Memory面板快照对比Detached DOM和组件实例、Allocation Timeline追踪未清理的副作用源头。

单页应用(SPA)切换路由时的内存泄漏,本质是组件、状态、监听器或定时器未随路由卸载而释放,导致对象持续驻留。检测不靠猜,关键在“可重复操作 + 可对比数据”。下面分三步直击问题:
一、用浏览器任务管理器快速初筛
打开 Chrome(隐身模式避免插件干扰),访问页面后按 Shift+Esc 调出任务管理器,找到对应标签页的 “内存” 列:
- 静置页面 10 秒,观察内存是否稳定在某个区间;
- 执行一次路由切换(如从 /home → /list → /home),等待 10 秒,看内存是否回落至接近初始值;
- 重复该操作 5–8 次,若每次切换后内存最低点都比上一次高 5MB 以上,基本可判定存在泄漏。
二、用 Memory 面板拍快照精准定位
这是最常用也最有效的手段,聚焦“对象是否被真正销毁”:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 打开 DevTools → Memory 面板,选择 Heap snapshot;
- 点击 Take Snapshot,记为 Snapshot 1(初始状态);
- 手动切换路由 3 次(例如 /a → /b → /a → /b),确保组件完成挂载与卸载;
- 再拍一张快照,记为 Snapshot 2;
- 选中 Snapshot 2,在右上角视图切换为 Comparison,对比 Snapshot 1;
- 重点关注:
- Detached DOM trees —— 表示已从文档移除但 JS 仍持有引用的节点;
- 构造函数名含 VueComponent、ReactComponent 或你项目中组件类名,且数量持续增加;
- Closure 类型对象 Retained Size 明显偏大,可能闭包捕获了大型数据或 DOM。
三、结合 Allocation Timeline 追踪泄漏源头
快照只能告诉你“谁还在”,Timeline 能告诉你“它什么时候来的、为什么没走”:
立即学习“Java免费学习笔记(深入)”;
- 在 Memory 面板切换到 Allocation instrumentation on timeline;
- 点击 Start,执行一次完整路由切换(进入 → 交互 → 离开);
- 停止录制,查看时间轴中蓝色条(新分配对象)是否在“离开后”仍长期存活(未变灰);
- 点击某段持续存活的蓝色区域,右侧会显示调用栈 —— 直接定位到创建该对象的代码行,比如:
router.beforeEach中意外保留了组件实例
useEffect或onUnmounted里漏写了removeEventListener或clearInterval
不复杂但容易忽略:每次路由切换都应是一次“干净的启停”。泄漏往往不出现在渲染逻辑里,而出现在副作用清理环节。


















