我如何协助IE的有缺陷的垃圾收集器?

时间:2011-08-20 21:52:29

标签: javascript internet-explorer garbage-collection

我有一个JavaScript应用程序,它使用XMLHttpRequest来获取和解析大约60,000个XML文档。但是,IE的内存使用量增长很快,最终程序崩溃了。我怀疑这与IE的JScript GC有关。以下是我的代码的简化版本:

在代码上方,我声明了两个变量:

var xmlhttp;
var xmlDoc;

当代码首次开始运行时,我设置了xmlhttp的值:

xmlhttp = new XMLHttpRequest();

然后脚本进入主循环:

function loadXML() {

    xmlhttp.abort(); 
    xmlhttp.open("GET", url, false);
    xmlhttp.setRequestHeader('Content-Type', 'text/xml', 'Pragma', 'no-cache');
    xmlhttp.send("");
    while (xmlhttp.readyState != 4) { }
    xmlDoc = xmlhttp.responseXML;
    setTimeout("readXML()",0);

}


function readXML() {

    //Reads the XML.
    //If all data has been retrieved, exit loop.
    //Else, change the url and go back to loadXML()

}

Google Chrome运行代码就好了,没有任何错误。但是,IE崩溃之前会出现大约2000次“内存不足”错误。垃圾收集器没有这样做;工作?我可以重写代码以防止出现问题吗?

2 个答案:

答案 0 :(得分:3)

您根本不应使用busy循环来等待XMLHttpRequest的结果。此外,没有理由将xmlhttp对象公开。相反,在每次调用时创建一个新的并注册回调:

function loadXML() {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", url, false);
    xmlhttp.setRequestHeader('Content-Type', 'text/xml', 'Pragma', 'no-cache');
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4) {
        xmlDoc = xmlhttp.responseXML;
        readXML();
      }
   };
   xmlhttp.send("");
}

答案 1 :(得分:1)

你应该按照phihag的建议来更好地处理xml请求并等待它们完成。

然后我建议将旧的xmlhttp对象清零并为每个连续的请求创建一个新的对象,这样每个旧的请求都可以完全释放:

你没有告诉我们你如何运行相同的东西60,000次,所以我无法真正帮助解决该代码的细节,但是如果xmlhttp对象本身在每个xmlhttp请求上泄漏了一些内存,那么就抛出每次离开旧物体并创建一个新物体可能有所帮助。

我们也无法看到你在readXML中做了什么,可能会泄漏,或者你在循环和获取下一个请求的代码中正在做什么。你可能会泄漏函数闭包,你可能有圆形对象引用等等......