无需登录 数据私有 本地保存

简易内存泄漏检测 - 快照对比

14
0
0
0

内存泄漏检测器

快照对比模式 · Heap Snapshot Diff
实时监控中 API
当前堆使用
--
--
堆大小限制
--
浏览器分配上限
快照数量
0
已保存快照
泄漏风险
--
等待数据
内存趋势图
时间轴 堆内存 快照点
快照列表

尚未拍摄快照
点击「拍摄快照」开始

点击选择快照A(蓝框),再选快照B(红框)进行对比
当前活跃模拟对象 0 个对象
类型ID大小泄漏创建时间
暂无模拟对象,点击「模拟分配」或「模拟泄漏」创建
常见问题 & 知识点
🔍 什么是内存泄漏?
内存泄漏是指程序中已不再需要使用的内存,由于错误的引用关系未能被垃圾回收器(GC)回收,导致可用内存逐渐减少。在长时间运行的前端应用中,内存泄漏会导致页面变慢、卡顿甚至崩溃。JavaScript的垃圾回收主要基于引用计数和标记清除算法,当对象之间形成循环引用或全局变量持有不再需要的对象引用时,就会发生泄漏。
📋 JavaScript常见内存泄漏原因有哪些?
  • 意外的全局变量:未使用 var/let/const 声明的变量自动成为全局变量,不会被GC回收。
  • 被遗忘的定时器:setInterval/setTimeout 未通过 clearInterval/clearTimeout 清除,回调持续持有外部引用。
  • 未移除的事件监听器:DOM元素被移除但事件监听器仍绑定,导致元素无法被回收。
  • 脱离DOM的引用:JavaScript变量仍然引用已从DOM中移除的节点。
  • 闭包陷阱:闭包意外持有大量外部变量,导致这些变量无法被回收。
  • 缓存未清理:Map/Set/Array等数据结构无限增长,没有淘汰策略。
📸 如何使用快照对比检测内存泄漏?
快照对比(Snapshot Diff)是检测内存泄漏的核心方法:
1. 在操作前拍摄第一个快照(基线);
2. 执行一系列操作(如页面交互、数据加载);
3. 操作完成后拍摄第二个快照;
4. 对比两个快照,关注新增且持续存在的对象——这些很可能是泄漏。如果反复执行"操作→快照→对比"循环后,某些对象数量持续增长,基本可以确认存在内存泄漏。本工具通过模拟对象来演示这一流程。
🛠 performance.memory API是什么?
performance.memory 是Chrome浏览器提供的非标准API,包含三个属性:usedJSHeapSize(已使用堆大小)、totalJSHeapSize(当前堆总大小)、jsHeapSizeLimit(堆大小上限)。该API仅在Chrome中可用,且在某些环境下需要启用特殊标志。本工具优先使用该API获取真实内存数据,如不可用则使用模拟数据。
🔄 如何触发JavaScript垃圾回收?
JavaScript的垃圾回收是自动的,开发者无法直接控制。在Chrome中,可以通过 window.gc() 手动触发(需启动时添加 --js-flags="--expose-gc" 标志)。在普通环境下,可以尝试分配大块内存然后立即释放来间接"提示"GC运行,但这并不保证。在Chrome DevTools的Performance面板中,点击垃圾桶图标也可以触发GC。
⚡ 内存泄漏 vs 内存膨胀的区别?
内存泄漏是无意中保留了不再需要的对象引用,导致内存无法回收;内存膨胀则是有意但过度使用内存(如加载过多数据、缓存过大)。两者都导致内存占用增长,但泄漏是bug,膨胀是设计问题。快照对比可以帮助区分:如果对象数量在每次操作后持续净增长,通常是泄漏;如果只是单次加载数据量大,则可能是膨胀。
🔧 Chrome DevTools如何检测内存泄漏?
Chrome DevTools提供了三种主要工具:Heap Snapshot(堆快照)用于查看内存中所有对象;Allocation instrumentation on timeline(时间轴分配记录)用于实时观察内存分配;Allocation sampling(分配采样)用于低开销的内存分析。专业排查通常使用堆快照的对比模式,在两个快照之间按"对象计数差异"排序,快速定位泄漏源头。
💡 如何避免闭包导致的内存泄漏?
闭包本身不会导致泄漏,但不当使用会:
1. 避免在闭包中引用大型对象或DOM节点;
2. 及时解除不再需要的引用(如将变量设为null);
3. 使用WeakMap/WeakSet存储可被GC回收的键值对;
4. 在组件销毁时清理闭包中持有的引用(如在React的useEffect中返回清理函数)。