2017-04-06 64 views
10

在Google Chrome中運行我的KnockoutJS v3.4.2(測試)應用程序時遇到問題。
我的頁面的內存使用量不斷增加。KnockoutJS foreach綁定導致內存泄露

測試代碼是一個非常簡單的一段代碼,改變所述物品中可觀察到的陣列每秒:

HTML:

<html> 
    <head> 
     <title>KnockoutJS</title> 
    </head> 
    <body> 
     <h1>Foreach test</h1> 
     <ul id="ul-numbers" data-bind="foreach: { data: listOfItems }"> 
      <li> 
       <span data-bind="text: $data"></span> 
      </li> 
     </ul> 

     <script type="text/javascript" src="./lib/knockout.js"></script> 
     <script type="text/javascript" src="./index.js"></script> 
    </body> 
</html> 

的JavaScript:

var vm = { 
    listOfItems: ko.observableArray() 
}; 

window.setInterval(function updateList(){ 
    var array = []; 

    for(var i = 0 ; i < 1000; i++){ 
     var num = Math.floor(Math.random() * 500); 
     array.push(num); 
    } 

    vm.listOfItems(array); 
}, 1000); 

ko.applyBindings(vm); 

內存使用情況:

  • 在Firefox的內存使用量不會增加:
    開始:459.6 MB --->後+ - 4小時:279.4 MB

  • 在Chrome的內存使用量不斷增加(個別標籤的存儲器中):
    開始:52.912 MB --->後+ - 1小時:566.120 MB

  • 在邊緣上的內存使用量也不斷增加(單個標籤的內存):
    開始:109.560 MB --->後+ - 4小時:385.820 MB

難道我做錯了什麼在這段代碼中?或者這是Google Chrome或KnockoutJS中的錯誤?

+1

如果您不使用'array',而是在函數的開頭調用'vm.listOfItems.removeAll()',然後在循環內部調用'vm.listOfItems.push(num)'(忽略調用'vm.listOfItems(array)'在最後)? – haim770

+0

或者,您可以嘗試'vm.listOfItems(array.slice(0));'以防止Knockout保留對原始'array'的引用並允許GC處理它 – haim770

+0

使用removeAll進行測試,但仍然是相同的行爲。 –

回答

1

顯然,這是一個瀏覽器的問題。

當我現在運行我的測試項目時,內存不會增加。
測試項目可以在這裏找到:https://github.com/knockout/knockout/issues/2223

解決在谷歌瀏覽器版本'58 .0.3029.110'。

0

即使您要替換observable中的數組,它們仍會附加到DOM。在將新元素添加到陣列之前,您需要手動刪除它們。

事情是這樣的:

var vm = { 
    listOfItems: ko.observableArray() 
}; 

window.setInterval(function updateList(){ 
    var array = []; 
    vm.listOfItems.removeAll();//<--this is the important line 
    for(var i = 0 ; i < 1000; i++){ 
     var num = Math.floor(Math.random() * 500); 
     array.push(num); 
    } 

    vm.listOfItems(array); 
}, 1000); 

ko.applyBindings(vm); 

見#2在這個帖子:https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

+0

這並不能解決問題,我們已經嘗試過。 (請參閱我的問題的評論) –