2017-04-06 87 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

这并不能解决问题,我们已经尝试过。 (请参阅我的问题的评论) –