2012-03-21 44 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,這可能會取消先前的調用。