7

ボタンをクリックした後でウェブワーカーを呼び出すアプリがあります。計算は、UIを解放するために作業者に移動され、計算が行われている間にユーザーの操作に応答します。ウェブワーカー(ガベージコレクタ)を使用してメモリリークが発生する可能性があります

すべてが正常になり、約0.8-1.5秒後に作業者が応答を送信します。 worker.onmessageでは、必要なすべてのDOMアクションを実行します。しかし、このGCが現れた後、実際にはCPUに応じて2秒以上UIがブロックされます。これは本当に私を混乱させています。なぜなら、UIブロッキングは私が避けたいものだからです。あなたはGCイベントがちょうどすべてのDOM操作の後に起こる見ることができるようにhttp://i.imgur.com/zUoHa.jpg

:ここ

は、タイムライン/メモリコンソール]タブのスクリーンショットです。実際には、再描画イベントは1つしかありません(DocumentFragmentが使用されます)。

jsのメインコード:

var sortWorker = new Worker('js/contactsorter.js'); 
sortWorker.onmessage = function(e) { 
    var messages = []; 
    e.data.forEach(function(userDoc) { 
     var contactSection = _drawContact(userDoc); 
     messages.push(contactSection); 
    }); 

    meta.append(messages); // this actually appends document fragment as a child 
}; 

sortWorker.postMessage(postMessageData); 

contactsorter.js(労働者):

onmessage = function(e) { 
    var uid, output = [], usersStat = {}; 

    // calculations... 

    postMessage(output); 
    close(); 
}; 

は、この場所ではないか、これらのGCイベントを回避するための方法はありますか?

UPD:GCイベントの時間は、作業者に送信されたデータ量によって異なると思われます。 UPD2:シャットダウンと起動後にGCイベントが2回発生するため、UIが1秒未満でブロックされます。え?

+0

オブジェクトの大きさはどれくらいですか?幾つ?どんな種類の数字が話していますか?どんなDOMノードを作成していますか? GCイベントはソートされた連絡先の数に比例して直線的に変化しますか? –

+0

JSON.stringifyによると約2Mです。これはオブジェクトを子として持つオブジェクトです。作業者の応答(配列を出力する)の後、私はDocumentFragmentを作成し、およそを追加します。それに400の "div"要素があります。その後、私はDOMにフラグメントを追加します。最後の質問について - テストをするためにコードを書き直す必要があるので、少し後でコメントします。Btw:new UPD –

+0

最後の質問については、いいえ、データ量に応じてGCイベントはスケールされません。さらに、私はタイムライン上でそれを見つけることさえできませんhttp://i.imgur.com/psGpr.pngこの期間は、UIがクロックされている。 –

答えて

3

ウェブワーカーにとって覚えておくべきことは、特にあなたの例で使用されているように、ワーカーに送るときにオブジェクトをクローンしていることです。だから、愚かな例でこれを介して実行することができます:

  1. は大きなオブジェクトを作成します(あなたは2Mはすごい...博...コメントで言った) - 2Mは、メインスレッド2M労働者へ
  2. ポスト、中に割り当てられましたメインスレッドはまだ何か余分なものはメインスレッドであなたのオブジェクト/配列をJSONifyするために毛羽立ちとして作成されました。従業員は2Mになります。
  3. ここでワッカーの2M + GCに待っていて、今起こっているかもしれません...新しいジェネレーションオブジェクトの一定量がしきい値を超えた後にGCがトリガします...新しいオブジェクトとDOM要素のトンを作成した後、 D
  4. Workerがメッセージで応答し、新しい2M(yay)のメインスレッドで2Mを新たに作成し、オブジェクトをJSON化するために必要なfluffメモリオブジェクトを仮定します。

あなたは、これはクロムアプリ(別のコメント)と言ったので、その後、多分あなたは譲渡オブジェクトにあなたを使用する、などのコースの一時的なオブジェクトの作成をクローニングオブジェクトを避けるためにTransferable Objectsを利用するためにあなたのコードを再構築することができます配列バッファーとして再構成する必要があり、それ自体が暗い魔法です。

+0

* "あなたはコメントで2Mと言っています... wtf ... wow" * - グラフィックス、オーディオ、分析ソフトウェアなどのアプリケーションでは、より大きなものが普通です。私はtransferablesを使用して問題なくここに12 GB(!)の配列を渡しています。 –

+0

@JohnWeisz - 最近、私もWebAudioなどでより大きなオブジェクトを使用していますが、2013年後半にはバックマシンが多く見えるようになりました。彼の実際の問題は、一時的なオブジェクトのロードを作成することや、ループやマッパーの一部として、DOMで何をしているのかわかりません。 –

関連する問題