javascript内存泄漏

pus*_* 22 7 javascript memory-leaks

我刚刚注意到,一些JavaScript我,刚才已经书面似乎泄漏内存,它相当一段简单的代码 - 得益于jQuery的 - 但我能看着它在任务管理器运行,内存使用量由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);
});
Run Code Online (Sandbox Code Playgroud)

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

我应该清理getJSON调用吗?

TIA.

jfr*_*d00 6

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

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

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

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

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

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

我看到的唯一封闭在这里是$(document).ready()封闭,这是你想要的,它只创建一次,所以它应该不会泄漏.

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

olddata = json;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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