小编典典

简单的jQuery Ajax调用会泄漏Internet Explorer中的内存

ajax

我创建了一个网页,每秒进行一次Ajax调用。在Internet Explorer 7中,它严重泄漏内存(大约15分钟内20 MB)。

该程序非常简单。它只是运行一个进行Ajax调用的JavaScript函数。服务器返回一个空字符串,而JavaScript代码则不执行任何操作。我setTimeout过去每秒钟运行一次该函数,并且我正在使用Drip来观看该事件。

来源如下:

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load('jquery', '1.4.2');
      google.load('jqueryui', '1.7.2');
    </script>
    <script type="text/javascript">
      setTimeout('testJunk()',1000);
      function testJunk() {
        $.ajax({ url: 'http://xxxxxxxxxxxxxx/test', // The url returns an empty string
                 dataType: 'html',
                 success: function(data){}
               });
        setTimeout('testJunk()',1000)
      }
    </script>
  </head>
  <body>
    Why is memory usage going up?
  </body>
</html>

如何堵塞这种泄漏?我有一个真正的应用程序,它会以这种方式更新大表,但是如果不加注意,它将占用数GB的内存。

编辑 :好的,所以在提出一些好的建议之后,我将代码修改为:

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load('jquery', '1.4.2');
      google.load('jqueryui', '1.7.2');
    </script>
    <script type="text/javascript">
      setTimeout(testJunk,1000);
      function testJunk() {
        $.ajax({ url: 'http://xxxxxxxxxxxxxx/test', // The url returns an empty string
                 dataType: 'html',
                 success: function(data){setTimeout(testJunk,1000)}
               });
      }
    </script>
  </head>
  <body>
    Why is memory usage going up?
  </body>
</html>

不过,这似乎没有什么区别。我没有对DOM做任何事情,如果我注释掉Ajax调用,则内存泄漏将停止。因此,看起来泄漏完全在Ajax调用中。jQuery
Ajax是否会固有地创建某种循环引用?如果是,我如何释放它?顺便说一下,它不会在Firefox中泄漏。

有人建议在另一台VM上运行测试,然后查看结果是否相同。我没有设置另一台VM,而是发现了一台运行带有Internet Explorer 8的XP
Home的笔记本电脑。它出现了同样的问题。

我尝试了一些旧版本的jQuery并获得了更好的结果,但是直到我放弃jQuery中的Ajax并使用了更传统(更丑陋)的Ajax时,问题才完全消失。


阅读 262

收藏
2020-07-26

共1个答案

小编典典

问题似乎出在Internet Explorer中的jQuery 1.4,以及程度较小的1.2和1.3版本中。

1.4.0、1.4.1和1.4.2均出现严重的内存泄漏。

1.2.3、1.2.6、1.3.0、1.3.1和1.3.2都显示出小得多的泄漏(10分钟后大约100 KB)。

我还尝试了一种以更传统的方式调用Ajax的程序版本:

<html>
  <head>
    <script language="javascript" type="text/javascript">
      function getHTTPObject() {
        var xmlhttp;
        /*@cc_on
        @if (@_jscript_version >= 5)
          try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
          } catch (e) {
            try {
              xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (E) {
              xmlhttp = false;
            }
          }
        @else
        xmlhttp = false;
        @end @*/
        if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
          try {
            xmlhttp = new XMLHttpRequest();
            if (xmlhttp.overrideMimeType) {
              xmlhttp.overrideMimeType("text/xml"); 
            }
          } catch (e) {
            xmlhttp = false;
          }
        }
        return xmlhttp;
      }
      var ajaxObject = getHTTPObject();
      setTimeout(testJunk,1000);
      function testJunk() {
        ajaxObject.open('POST', 'http://XXXXXXXXXXXXXXX/delme2', true);
        ajaxObject.onreadystatechange = handleAjaxResponse;
        ajaxObject.send(null);
      }
      function handleAjaxResponse() {
        if (ajaxObject.readyState==4) {
          setTimeout(testJunk,1000);
        }
      }
    </script>
  </head>
  <body>
    <div id="test">Why is memory usage going up?</div>
  </body>
</html>

这完全消除了泄漏。

因此,看来我必须重复我的Ajax调用丑陋的旧方法,直到jQuery专家们解决了这个问题。

2020-07-26