javascript内存泄漏

时间:2011-08-04 21:24:57

标签: javascript memory-leaks

我刚刚注意到,我写的一些javascript似乎是在泄漏内存,这是一段相当简单的代码 - 感谢jquery - 但是我可以看到它在taskmanager中运行并且内存使用情况正在慢慢点击在4到40个字节之间。

我正在做的是通过getJSON在asp mvc控制器/动作上抛出一些数据:

$(document).ready(function () {
    var olddata = "";
    window.setInterval(function () {
        var options = JSON.stringify({
            orderby: "name"
        });
        var params = {
            options: options,
            data: olddata ? JSON.stringify(olddata) : ""
        };
        $.getJSON("/Home/GetTasks", params, function (json) {
            olddata = json;
            json = null;
        });
        params = null;
        options = null;
    }, 1000);
});

我已经提高了计时器值,只是为了更容易看到问题。我显然在这里做错了什么但看不到什么。

我应该清理getJSON电话吗?

TIA。

1 个答案:

答案 0 :(得分:6)

你怎么知道你实际上是在泄漏记忆?

在4和40字节这样的小数字中,您可能只看到堆增长,但堆中的一些新块是“免费的”并且可供将来使用,因此当整个应用程序内存使用增长时,内存不会实际上已经泄漏,将来可以使用,所以它不会永远增长。

如果这是您实验的整个范围,那么我认为代码没有任何问题。

这里有三个功能闭包。 $(document).ready()闭包会持续你的代码的生命周期,但它只是一次性的交易所以应该没有问题。

传递给setInterval()的匿名函数使$(document).ready()闭包保持活动状态。对setInterval()匿名函数的每次调用都应该是一个新的调用,它将获得一组新的局部变量,并在先前调用运行完成时释放它们的旧变量。

传递给getJSON()的匿名函数在setInterval匿名函数上创建了一个闭包,但该闭包应该只持续到getJSON函数完成,并且它应该释放setInterval()匿名函数闭包。

我看到的唯一闭包就是$(document).ready()闭合,这是你想要的,它只创建一次所以它不应该导致泄漏。

getJSON匿名函数中的所有局部变量将在完成时释放。来自getJSON调用的唯一数据是您的分配:

olddata = json;

但是,每个连续的分配只是替换上一次调用中的数据,因此以前的数据不再被引用并且可供垃圾收集器回收。

这里没有DOM操作,因此DOM和JS之间没有交叉或循环引用的机会。

我的结论是,我没有看到任何会泄漏的东西。我看到很多东西使用临时内存,所以我怀疑你在进程中看到的内存使用只是堆增长,但增长的方式是已经增长的内存最终会被重用。如果浏览器也缓存了JSON结果,那么您也可能看到内存缓存增长。

不幸的是,在今天的浏览器中,很难分辨它何时真的是内存泄漏而不是缓存,一般堆等使用的浏览器内存的临时扩展......在极端情况下,你可以将所有缓存设置得非常小并运行这个很长一段时间(数十万次迭代)。如果它不是泄漏,内存使用最终应该变平。如果是泄漏,内存使用量应继续相对线性增长。

免责声明:这里的一个免责声明是我假设jQuery函数$.getJSON()不会自行泄漏,并且总是以清理它创建的闭包的方式完成,即使ajax呼叫不成功。