KnockoutJS foreach绑定导致内存泄露
在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中的错误?
显然,这是一个浏览器的问题。
当我现在运行我的测试项目时,内存不会增加。
测试项目可以在这里找到:https://github.com/knockout/knockout/issues/2223
解决在谷歌浏览器版本'58 .0.3029.110'。
即使您要替换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/
这并不能解决问题,我们已经尝试过。 (请参阅我的问题的评论) –
如果您不使用'array',而是在函数的开头调用'vm.listOfItems.removeAll()',然后在循环内部调用'vm.listOfItems.push(num)'(忽略调用'vm.listOfItems(array)'在最后)? – haim770
或者,您可以尝试'vm.listOfItems(array.slice(0));'以防止Knockout保留对原始'array'的引用并允许GC处理它 – haim770
使用removeAll进行测试,但仍然是相同的行为。 –