【问题标题】:How to destroy a JavaScript object?如何销毁 JavaScript 对象?
【发布时间】:2012-05-02 00:55:04
【问题描述】:

最近,我遇到了一个应用程序,它消耗了太多内存并且以 10 MB/秒的速度增加。

所以,我想知道如何销毁 JavaScript 对象和变量,以减少内存消耗并且我的 FF 不会被销毁。

我每 8 秒调用一次我的两个脚本,而无需重新加载页面。

function refresh() {
    $('#table_info').remove();
    $('#table').hide();
    if (refreshTimer) {
        clearTimeout(refreshTimer);
        refreshTimer = null ;
    }
    document.getElementById('refresh_topology').disabled=true; 
    $('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
    $("#topo").hide();
    $('#root').remove();
    show_topology();
}

如何查看导致内存开销的变量,停止该进程执行的方法是什么?

【问题讨论】:

  • 您是否考虑过使用闭包隔离部分代码?
  • 你有没有尝试过?喜欢使用obj = null
  • A) show_topology 做什么? --- B) 你有没有清理过你添加到#td_123 的东西? --- C) 在某个地方有这个的现场版本吗?

标签: javascript object destroy


【解决方案1】:

您可以将所有代码放在一个命名空间下,如下所示:

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

使用delete 关键字将删除对属性的引用,但在底层,JavaScript 垃圾收集器 (GC) 将获得有关要回收哪些对象的更多信息。

您还可以使用 Chrome 开发者工具获取应用的内存配置文件,以及应用中的哪些对象需要缩减。

【讨论】:

  • 按 F12 获取开发者工具。转到配置文件选项卡,然后单击开始以启动配置文件。您可以在 JS CPU、CSS 选择器上进行分析,还可以拍摄堆快照。
  • 或在最新的 chrome 中在 js 控制台中输入性能一词
  • 也许这很明显,但是您可以将命名空间命名为“g”之类的名称,并节省大量输入。使用 g.curItem=... 而不是 var curItem=... 并保存输入以及允许 g=undefined 清除所有全局内存分配。
【解决方案2】:

您不能删除对象,当不再引用它们时它们会被删除。您可以使用delete 删除引用。

但是,如果您在对象中创建了循环引用,您可能需要解耦一些东西。

【讨论】:

  • 你能添加一个循环引用的例子,它不会被垃圾收集器捕获吗?求朋友! ;)
  • @emilhem 你可以参考垃圾收集器,它会删除自己和互联网 - 内爆可能会在 CERN 创建一个黑洞。你想过这个例子吗?
【解决方案3】:

虽然现有的答案已经给出了解决问题和问题后半部分的解决方案,但它们并没有为问题前半部分的自我发现方面提供答案:

“我如何查看是哪个变量导致内存开销...?”

它在 3 年前可能没有那么强大,但 Chrome 开发者工具的“Profiles”部分现在已经非常强大且功能丰富。 Chrome 团队有一个insightful article 使用它,因此还有 garbage collection (GC) 如何在 javascript 中工作,这是这个问题的核心。

由于delete 基本上是 Yochai Akoka 当前接受的答案的根源,因此记住 delete 的作用很重要。如果不结合接下来两个答案中 GC 如何工作的概念,它是无关紧要的:如果存在对对象的现有引用,则它不会被清理。答案更正确,但可能不那么受欢迎,因为它们需要更多的思考,而不仅仅是写“删除”。是的,一种可能的解决方案可能是使用delete,但如果有另一个内存泄漏引用也没关系。

Another answer 适当地提到了循环引用,Chrome 团队文档可以提供更清晰的说明以及验证原因的工具。

由于此处提到了delete,因此提供资源Understanding Delete 也可能很有用。虽然它确实没有进入任何与 javascript 的垃圾收集器真正相关的实际解决方案。

【讨论】:

    【解决方案4】:

    构建您的代码,使您的所有临时对象都位于闭包内,而不是全局命名空间/全局对象属性,并在您完成它们后超出范围。 GC 会处理剩下的事情。

    【讨论】:

      【解决方案5】:

      我遇到了这样的问题,并且想简单地更改有问题对象的子对象的 innerHTML。

      adiv.innerHTML = "<div...> the original html that js uses </div>";
      

      看起来很脏,但它救了我的命,因为它有效!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-09
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多