解释chrome任务管理器中的内存使用情况

时间:2014-07-15 11:19:20

标签: javascript google-chrome-devtools

我从一个大型java脚本应用程序中的内存泄漏调查开始,该应用程序在基于webkit和sfx(java脚本核心引擎)的浏览器中作为小部件运行。过了一会儿,我发现内存的来源随着时间的推移而增加。碰巧是$.ajax(..)

好的,我想,让我们尝试不同版本的jquery或直接使用XMLHttpRequest - 同样的结果。然后我在谷歌浏览器上检查它并感到惊讶,因为堆分析器既没有显示js对象数量的增加也没有增加堆大小,而chrome任务管理器显示内存和私有内存增加。我测试的代码如下:

var Main = {};
var xhr = new XMLHttpRequest();

function makeRequest() {
    xhr.timeout = 2000;
    xhr.ontimeout = function() {
        xhr.abort();
    }
    xhr.onreadystatechange = function() {
        if (xhr.readyState != 4) return;
    };

    xhr.open("POST", "", true); //async post request to local server
    xhr.send("{}");
}

Main.onLoad = function()
{
    setInterval(function() { makeRequest(); }, 3000);
}

那么,这种行为可以吗?这不是本机内存泄漏的迹象吗?

P.S。我在Windows 7企业版上使用版本为35.0.1916.153的chrome。

1 个答案:

答案 0 :(得分:2)

According to the spec,xhr不会自动GC。

  

4.2垃圾收集

     

如果状态为XMLHttpRequest对象,则不得对其进行垃圾回收   OPENED和send()标志置位,其状态为HEADERS_RECEIVED,或   其状态为LOADING,并且已注册一个或多个事件侦听器   其类型是readystatechange,progress,abort,error,load,   超时和loadend。

     

如果XMLHttpRequest对象在其连接时被垃圾收集   仍处于打开状态,用户代理必须终止请求。

This article对此问题和类似问题有很好的解释。通常的解决方法是在xhr = null之后通过xhr.send()清除回调中对宿主对象的引用。我说通常的修复,因为你没有分配更多的xhr对象或在这个例子中对结果做任何事情。如你所说,堆没有改变,看起来你没有泄漏。

单独使用chrome任务管理器无法告诉您是否有泄漏。我发现this article是一个有用的教程,介绍如何使用chrome的devtools来诊断内存泄漏。您需要手动触发GC并验证内存不会持续增长。如果您发现确实存在内存泄漏,则可以使用devtools来确定哪些对象不属于保留路径,但仍在内存中(有关如何在该文章中执行此操作的详细信息)。