使用分离的元素工具调试 DOM 内存泄漏
发垃圾回收
接下来,在浏览器中 (GC) 垃圾回收:
-
在"分离的元素" 工具中,单击****
收集垃圾"图标。) 图标。
-
单击" 获取分离的元素 (
。) 图标。
选择" 收集垃圾" 时,浏览器将运行垃圾回收。 选择"获取分离的元素"时,"**** 分离的元素"工具将显示无法进行垃圾回收的所有已分离元素。 如果应用程序不会重复使用这些分离的元素,则这些分离的元素可能是内存泄漏。
标识保留已分离元素的 JavaScript 代码
找到无法进行垃圾回收的分离元素后,可以使用分离元素工具中的"分析"按钮识别**** 仍在引用已分离**** 元素的页面上运行的 JavaScript 代码。 " 分析 "按钮获取堆快照,并使用已分离元素在堆中的位置填充该元素的 ID :
有关堆快照详细信息,请阅读使用内存 工具记录堆快照。
若要标识引用已分离元素的 JavaScript 代码,请执行以下操作:
-
在分离的元素工具中,单击分析
。) 图标。
内存 工具 将在 DevTools 的底部面板中打开。
-
从 "分离的元素" 工具中,选择已分离元素的 Id 字段。
底部面板中的"内存"工具会自动选择堆中引用已分离元素的对象。 我们将这些对象称为 保留者:
-
在底部 面板 的"内存"工具中,选择"room.js ** :13"**。
" 源 "工具在顶部面板中打开到文件的第 13 ** 行 **room.js。
-
在room.js
hide()
函数中****,演示应用程序的 JavaScript 代码会将会议室中的每条消息添加到数组unmounted
中。 数组unmounted
是引用已分离元素的对象:
现在,你已确定阻止浏览器对已分离元素进行垃圾回收的保留器!
标识导致其他保留的 DOM 节点
由于 DOM 是一个完全连接的图形,因此当 JavaScript 将一个 DOM 节点保留在内存中时,它可能导致其他 DOM 节点随它一起保留。
若要标识导致保留整个树的已分离树中的原因节点:
-
单击 "分离
("图标中的"分离元素"。单击) "图标可销毁分离树内的父子链接:
-
单击"收集垃圾 (
图标。单击) 图标。
父子链接在分离的树内删除。
将所选目标更改为其他源
可以使用"选定目标"下拉列表检查不同源或帧中的分离元素。****
-
单击 "选定的目标 "下拉列表:
-
选择其他源。
新源显示在分离 的元素工具 中。
其他注意事项
在查找内存泄漏时,请记住泄露可能取决于应用程序的上下文。 对于演示应用程序,你发现了浏览器无法垃圾回收的已分离元素,并且你标识了保留已分离元素的 JavaScript。 但是,在演示应用程序的上下文中,保留聊天消息列表是有意义的,这样,如果用户切换回会议室 1,则保留消息日志。
下图以用户从 2 室导航回会议室 1 时重新附加的消息形式显示分离 的元素:
同样,当用户滚动过去时,社交媒体中的源可能会分离元素,当用户向后滚动时,再将它们重新附加到 DOM。 分离的元素并不总是表示内存泄漏,内存泄漏并不总是由分离的元素导致。
对于长时间运行的应用,仅泄露几千字节的小内存可能会随着时间的推移显著降低性能。 使用此框架的 web React知道React维护 DOM 的虚拟化副本。 无法正确卸载组件可能会导致应用程序泄露虚拟 DOM 的较大部分。
反馈
使用 分离元素 工具查找浏览器无法垃圾回收的分离元素,并找到仍在引用已分离元素的 JavaScript 对象。 通过更改 JavaScript 以释放 元素,可以减少页面上的分离元素数量。
当某个元素不再附加到文档对象模型 (DOM) 树,但仍由页面上运行的一些 JavaScript 引用时,应用程序中可能会发生内存泄漏。 这些元素称为 分离元素。 对于在已分离元素 (GC) 进行垃圾回收的浏览器,不得从 DOM 树或 JavaScript 代码引用该元素。