【问题标题】:When or in what condition should I nullify objects in jQuery?我应该在什么时候或在什么情况下使 jQuery 中的对象无效?
【发布时间】:2013-02-09 02:23:34
【问题描述】:

我正在开发一个大量使用 Javascript 并包含大量 DOM 操作的项目。随着代码的增长,我注意到有时在 Internet Explorer (9) 下页面加载时 Javasript 执行会有延迟(大约 1-2 秒)。这种延迟在 Firefox 上从未发生过。

例如:

// the actual code contains much more stuff
$("body").append("<p>paragraph</p>");

虽然p 是动态生成的,但它应该在现代浏览器上的页面加载后立即看到。但在 IE 上,有时我可以清楚地看到 p 在所有静态内容加载后被添加,这使得整个页面变得跳跃。

如果我重新启动 IE,延迟就消失了。但是,如果进行了大量的 DOM 操作,它会在下一页刷新时再次发生。

所以我在想这是否是由memory leak 引起的,因为我很少使对象引用无效。

var foo = $("#foo");
foo.on("click", function() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
    // nullify bar
    bar = null;
});
// nullify foo
foo = null;

问题:

  1. 是否应该像上面的示例一样在使用完 每个 对象引用后取消它们?

  2. 如果 Q1 的答案是否定的,我应该在什么时候或在什么情况下使对象引用无效?

  3. 除了无效之外,我还能做些什么来防止内存泄漏?

PS:几年前我读过一些类似的问题,它们主要针对 IE 6/7。

【问题讨论】:

  • 您是否尝试过使对象无效,然后进行测试以查看内存泄漏会发生什么?对于这些类型的事情,通常没有非常明确的答案。基于该分析的分析和优化可能是您能做的最好的事情。但希望有人有更好的回应:)
  • 我不确定你能否超越 IE 垃圾收集器的性能,但我可能是错的。如果你经常使用.append 和类似的函数,尤其是在循环中,它会占用大量内存;您可能想看看是否可以减少一点
  • 在这个特定的例子中,将变量设置为 null 不会帮助你。您可以阅读 ie 特定策略(即 dom 和垃圾收集存在特定问题)。但首先...测量内存以确保您确实存在内存泄漏。
  • 如果您正在使用循环执行某些操作,@ExplosionPills 的建议将通过在循环期间连接字符串中的所有 html 来实现,然后在循环完成后将整个内容附加一次.
  • @maxedison 不,我没有花时间使所有对象无效,因为代码有点长而且复杂。实际上我不太确定how to trigger the problem 在我的项目中。现在似乎是随机发生的。

标签: javascript jquery performance internet-explorer memory-leaks


【解决方案1】:

是否应该像上面的示例一样在使用完每个对象引用后取消它们?

不,这太过分了。

如果 Q1 的答案是否定的,我应该在什么时候或在什么情况下使对象引用无效?

当您不再需要它但它在仍然存在的功能范围内时。在您的示例中,foo 可以从单击处理程序中引用,因此只要处理程序附加到 DOM,它就不会被垃圾收集。然而,没有理由取消bar

除了无效化,我还能做些什么来防止内存泄漏?

  • 根本不使用变量。在您的示例中,您可以简单地使用链接:$("#foo").on(…);
  • 如果处理函数与使用它们的执行上下文无关,请在不同的范围内声明它们:
$(document).ready(function() {
    var foo = $("#foo");
    foo.on("click", showBar);
    // do anything else with `foo`
});
function showBar() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
});

几年前我读过一些类似的问题,它们主要针对 IE 6/7。

这是因为 IE6/7 在其垃圾收集器中存在一些错误(javascript, circular references and memory leaksMSDNarticles)。然而,上面提到的技术与此无关,它们假设一个正确工作的 GC。通过优化 GC,它们甚至可能不再需要,例如 V8 确实会收集实际上在范围内但不再使用的变量 (Debugging Revealing Module Pattern: functions not in scope until called?)。

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 2010-12-30
    • 1970-01-01
    • 2012-06-02
    相关资源
    最近更新 更多