85

最近,我遇到了我的一个应用程序,它消耗了太多内存并且以 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();
}

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

4

5 回答 5

99

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

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

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

您还可以使用 Chrome 开发人员工具来获取应用程序的内存配置文件,以及应用程序中的哪些对象需要按比例缩小。

于 2012-04-20T12:39:32.833 回答
32

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

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

于 2012-04-20T12:30:24.087 回答
30

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

“我怎样才能看到哪个变量导致内存开销......?”

3 年前它可能还没有那么健壮,但是 Chrome 开发者工具的“配置文件”部分现在已经非常强大并且功能丰富。Chrome 团队有一篇关于使用它的有见地的文章,因此还有垃圾收集(GC)如何在 javascript 中工作,这是这个问题的核心。

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

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

既然在这里提到,提供资源理解删除delete也可能有用。尽管它没有涉及任何与 javascript 的垃圾收集器真正相关的实际解决方案。

于 2015-10-16T17:47:05.483 回答
9

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

于 2012-04-20T12:29:19.663 回答
1

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

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

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

于 2013-06-10T20:20:06.263 回答