2017-04-06 25 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メガバイト --->の後に+ - 1時間:279.4メガバイト

  • はクロームでメモリ使用量を保持します(個々のタブのメモリ)増加:
    開始:52.912メガバイト ---> +の後 - 1時間:566.120メガバイト

  • エッジでメモリ使用量も(個々のタブのメモリを)増加し続ける:
    開始:109.560メガバイト --->の後に+ - 1時間:385.820メガバイト

私が何か間違ったことをしていますこのコードスニペットで?または、これは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

Google chromeバージョン'58 .0309.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

それは問題を解決しない、我々はすでにそれを試みた。 (私の質問のコメントを参照してください) –

関連する問題