2012-03-21 70 views
3

下面是一些代码,我在谷歌的Chrome 19.0.1061.1运行(正式版本125213)开发:内存泄漏一个XMLHttpRequest和setInterval

<html> 
<title>Memory Leak</title> 
<script type="text/javascript"> 
    (function(){ 
     this.window.setInterval(function() { 
      var xhr = new XMLHttpRequest(); 
      xhr.open('GET', '', false); 
      xhr.send(); 
     }, 50); 
    }).call(this); 
</script> 
</html> 

当我在Chrome检查内存使用://任务,我可以看到“私人内存”无限增长(8GB内存配置)。 如果我的代码示例更改上面类似的东西:

<html> 
<title>Memory Leak</title> 
<script type="text/javascript"> 
    (function(){ 
     var xhr = new XMLHttpRequest(); 
     var timeout = this.window.setInterval(function() { 
      xhr.open('GET', '', false); 
      xhr.send(); 
     }, 50); 
    }).call(this); 
</script> 
</html> 

它现在确定。

我不明白。 为什么保持对setInterval函数的引用有帮助,而为什么定义只有一个xhr有帮助,因为前面的声明是在闭包中?它仅与v8有关吗?

我将不胜感激您的见解。

+0

保持对超时的引用并不能帮助清理泄漏。它重新使用XHR对象,防止泄漏。注意:如果您尝试从服务器读取响应,则会在50ms内被覆盖,因此会中断响应。 – 2012-03-21 14:06:58

+0

- 为什么在范围函数上使用调用? (function(context){console.log(context)/ * window * /})(this); (function)(context){console.log(context)/ * window * /})(window); (function(){console.log(this)/ * window * /})(); – elmuchacho 2012-03-21 14:44:49

回答

8

在第一个示例中,您将在每次调用迭代器函数时实例化一个新的XMLHttpRequest对象。请求对象将至少停留在HTTP请求完成之前。每秒发起200次HTTP请求会阻止浏览器发生激烈的攻击,因为它不会实际执行所有请求;它会打开多少个并发连接是有限制的。

0

在第一个示例中,您正在每个间隔调用一个XMLHttpRequest()的新实例。在第二个例子中,你实例化一个副本并在代码的整个生命周期中使用它。这就是为什么在第一个例子中,你的内存不足。

1

这个http调用需要多长时间?如果这需要更长的时间然后50ms(这是一个非常短的时间),那么第一种情况会创建越来越多的挂起请求,而第二种情况是您重复使用相同的XMLHttpRequest,这可能会取消先前的调用。