在chrome dev工具中查找JS内存泄漏

时间:2012-08-13 07:43:33

标签: javascript jquery google-chrome-devtools

如果某些JS代码中存在内存泄漏,我正在使用chrome dev工具来解决问题。 内存时间轴看起来很好,内存按预期回收。

enter image description here

然而,内存快照令人困惑,因为它似乎存在泄漏,因为“分离的DOM树”下有条目。

“分离的DOM树”下的东西是等待垃圾收集还是这些真正的泄漏?

也有人知道如何找出对分离元素的引用持有什么功能吗?

enter image description here

3 个答案:

答案 0 :(得分:33)

这些元素在您的代码中被引用,但它们与页面的主DOM树断开连接。

简单示例:

var a = document.createElement("div");

a现在引用了已断开连接的元素,当a仍在范围内时,它无法进行GC。

如果分离的dom树在内存中持续存在,那么你将继续引用它们。用jQuery做这个有点容易, 只需保存对遍历结果的引用并保留它。例如:

var parents = $("span").parent("div");
$("span").remove();

现在引用了跨距,即使它看起来你无论如何都没有引用它们。 parents间接保留引用 通过jQuery .prevObject属性的所有跨度。所以做parents.prevObject会给出引用所有跨度的对象。

请参见此处的示例http://jsfiddle.net/C5xCR/6/。即使没有直接显示跨度会被引用, 它们实际上是由parents全局变量引用的,你可以看到Detached DOM树中的1000个跨度永远不会消失。

现在这里是相同的jsfiddle但是:

delete parents.prevObject

你可以看到跨度不再在分离的dom树中,或者在任何地方。 http://jsfiddle.net/C5xCR/7/

答案 1 :(得分:14)

  

“分离的DOM树”下的东西是等待垃圾收集还是这些真正的漏洞?

在拍摄快照之前,浏览器将运行垃圾收集并清除所有未引用的对象。因此堆快照始终只包含活动对象。因此,如果分离的DOM树位于快照中,则树中必须存在从JavaScript引用的元素。

  

也有人知道如何找出哪个函数持有对分离元素的引用?

在同一个分离的DOM树中应该有一个元素(或其中几个)具有黄色背景。这些元素是从JavaScript代码引用的。您可以找出哪些确切地引用了保留器树中的元素。

答案 2 :(得分:1)

由于您已经添加了jQuery标记,因此我怀疑这是一个jQuery 的事情。一个快速的谷歌带我到this page。使用jQ的detach方法时,对象的引用仍保留在内存中,因此可能会导致快照。

另一件事可能是jQuery手头有一个div节点,显然是保存在内存中,但从未添加到实际的dom中......某种document.createNode('div')没有附加它。这也会出现在内存快照中。你无法解决这个问题,jQuery使用它来解析字符串到html元素。

所以要从内存中删除一些元素,使用jQuery .remove()方法,你的内存将立即被清除 cf Esailija评论为什么{{ 1}}并不适合这里的账单
remove应该完全删除元素,但可能不会取消绑定事件。也许有些事情如下:

$('#someElem')[0].parentNode.removeChild($('#someElem')[0]);

而且,正如Esailija在他的回答中指出的那样,确保将对任何jQuery对象($('#someElem').detach();//to remove any event listeners $('#someElem')[0].parentNode.removeChild($('#someElem')[0]);//remove element all together )的引用分配给全局变量,因为他们不会被GC编辑。事实上,尽量避免使用全局变量 但是要简要回答一下你的问题,并清楚地说明:没有这些真正的内存泄漏,应该在var someRef= $('.someSelector');事件中释放内存。 jQuery对象被删除,因此所有引用都超出范围。至少,那是我的"研究" 引导我相信的。 Perhaps not entirely relevant, but just as a reference这里有一个关于内存泄漏的问题,我发布了一段时间后,我发现了一些事情......