如何帮助ie的有缺陷的垃圾收集器

How Can I Assist IE's Flawed Garbage Collector?

本文关键字:有缺陷 收集器 ie 何帮助 帮助      更新时间:2023-09-26

我有一个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次之前崩溃与"内存不足"的错误。垃圾收集器没有做它的工作吗?我可以重写我的代码来防止问题吗?

根本不应该使用忙循环来等待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("");
}

您绝对应该遵循phihag的建议,以更好的方式处理xml请求并等待它们完成。

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

您没有向我们展示您如何运行相同的事情60,000次,所以我无法真正帮助代码的细节,但是如果xmlhttp对象本身在每个xmlhttp请求上泄漏一些内存,那么扔掉旧对象并每次创建一个新对象可能会有所帮助。

我们也看不到你在readXML中做了什么,可能会泄漏,或者你在循环并获得下一个请求的代码中做了什么。你可能会泄漏函数闭包,你可能会有循环对象引用,等等…