【问题标题】:does jQuery .html() method leak memory?jQuery .html() 方法会泄漏内存吗?
【发布时间】:2012-11-15 13:34:34
【问题描述】:

我正在构建一个带有 requestAnimationFrame 循环的游戏,其中包括对 jQuery html() 方法的调用。它只是更新游戏操作旁边的状态窗口中的文本。

我注意到 Chrome 的时间线监视器,DOM 节点不断上升,每分钟数千个!当我从以下位置更改代码时:

// creates a ton of DOM nodes
$("#readout").html(data);

// DOM nodes does not increase over time
document.getElementById('readout').innerHTML = data;

“内存泄漏”消失了。

【问题讨论】:

  • 你选择每一个读数....保存 jquery 对象
  • 我试图以非常非常简单的方式复制这个问题,但我没有看到它。 jsfiddle.net/DvRAA
  • 没有扩展可能导致这种情况?

标签: jquery memory memory-leaks


【解决方案1】:

简短回答:不。

长答案:您的页面/代码中可能还有其他内容。

内存泄漏通常是由 Javascript 引擎和 DOM 之间的循环引用引起的。例如:

var div = document.getElementById('divId');
div.onclick = function() {
    doSomething(div);
};

脚本获取对页面上 div 的引用。到目前为止,我们很好。下一行将一个函数分配给 DOM 上的事件处理程序,创建从 DOM 到 Javascript 引擎的引用 - 泄漏的一半。函数体使用标签,它创建了一个闭包——标签引用与函数一起保存,以供将来调用它。这样就完成了标签 -> 函数(DOM -> JS)和函数 -> 标签(JS -> DOM)之间的循环引用,因此 2 将一直驻留在内存中,直到浏览器的进程被销毁。

因此,为了使您提到的任何一行代码泄漏,必须消除带有如上所述附加事件的标签(或遵循类似模式的数据)。但是,jQuery 的 .html(string) 不遗余力地阻止了这些:

// Remove element nodes and prevent memory leaks
elem = this[i] || {};
if ( elem.nodeType === 1 ) {
    jQuery.cleanData( getAll( elem, false ) );
    elem.innerHTML = value;
}

所以它会遍历 all 你正在运行 .html(string) 的标签内的标签,并在它们上运行 cleanData(),这反过来会这样做:

jQuery.removeEvent( elem, type, data.handle );

从而防止泄漏。

因此,为了使用此方法而不是 浏览器内置的 .innerHTML 泄漏内存,您必须触发一些非常晦涩的浏览器错误(似乎不太可能),或者更有可能是某些东西else 正在发生,你把它误认为是 jQuery 的 .html(string)。

【讨论】:

    【解决方案2】:

    始终使用.empty().html(...) 而不仅仅是.html()

    .empty() 将事件侦听器与您要移除的 DOM 对象解除绑定,并优雅地移除它们。

    【讨论】:

    猜你喜欢
    • 2011-01-10
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多