6

ID属性に動的に作成されたDOMオブジェクトの値を割り当てるとIE9がメモリをリークすることに気付きました。他の誰かがこれを体験しましたか、もっと重要なのは、回避策を知っていますか?それは他のブラウザでも漏れません、IE6のパスさえ!漏れコードのID属性の動的DOMオブジェクトのIE9メモリリーク

デモ:これは、単に追加し、連続してテーブルから行を削除し、後で参照するために使用される各列にIDを割り当て

"row.id = eid;"がなくてもリークは発生しません。

<html> 
    <head> 
     <script type="text/javascript"> 

     function addRow(tbl, index) { 
      var row = tbl.insertRow(index); 
      var eid = "loongrowid" + count; 
      row.id = eid; 

      for (var i = 0; i < 9; i++) { 
       row.insertCell(i); 
      } 

      return row; 
     } 

     function removeTableRow(tbl, index) { 
      var row = tbl.rows[index]; 
      tbl.deleteRow(index); 

     } 

     var count = 1; 

     function fillRow(row){ 
      row.cells[0].innerHTML = '<input type="checkbox"' + ' checked="checked"' + ' />'; 
      for (var i = 1; i < 9; i++) { 
       row.cells[i].innerHTML = count + " c"; 
      } 
      ++count; 
     } 

     var added = false; 

     function dostuff() 
     { 
      var tbl = document.getElementById("tbl"); 
      var i; 

      if (added) 
      { 
       for (i = 0; i < 20; ++i) 
       { 
        removeTableRow(tbl,1); 
       } 
      } 
      else 
      { 
       for (i = 0; i < 20; ++i) 
       { 
        var row = addRow(tbl, i+1); 
        fillRow(row); 
       } 
      } 

      added = !added; 
      setTimeout(dostuff, 1); 
     } 
     </script> 
    </head> 
    <body onload="setTimeout(dostuff, 1)"> 
    <h1 id="count">TESTING</h1> 
    <table id="tbl" style="width:100%;">  
    <tr> 
     <th>selected</th> 
     <th>date</th> 
     <th>time</th> 
     <th>place</th> 
     <th>device</th> 
     <th>text</th> 
     <th>state</th>   
     <th>status</th> 
     <th>quality</th> 
    </tr> 
    </table> 
    </body> 
</html> 

Iは表の行からすべての細胞を除去すると、メモリリークが縮小させることに気づいたので、私はそれがテーブルから削除された後IEが行へ保持推測。

また、getElementById(row.id)に頼るのではなく、ハッシュテーブルとして使用するために作成されたテーブル行をJavascriptオブジェクトに追加するという回避策を試しましたが、見えない何らかの理由でリークしました。

var hash = []; 

    // when creating row 
    row.extid = eid; // Note: this by itself causes no leak 
hash[eid] = row; 

    // when removing row 
delete hash[row.extid]; 
+0

あなたは 'setAttribute'でidを割り当ててみましたか?理論的には違いはありませんが、私たちは決して知らないのです。 – bfavaretto

+0

私はそれを試みましたが、それは何の違いもありませんでした。 –

+0

問題は、このコードの遅い作業またはIEのあまりにも多くのメモリを取っている? DOMに挿入しようとしましたが、最初にいくつかの変数に新しいHTMLをすべて集めましたか? – shershen

答えて

2

私の場合は、「実行中」の後に含まれているテストページを再読み込みするとメモリ使用量が一定に保たれる一時的に(リロード前に実行されていた時間と比較して)その後、再び上昇し始めた。

IEは、要素が削除された後、ID:d要素によって使用されたリソースを完全に削除しませんが、同じIDが再度ページに追加された場合、これらのリソースが再利用されるようです。

Ergoの場合、追加または削除されるIDは限定されたセットの一部であり、無制限のIDではないことを確認してください。テストページでは、整数ベースのIDが厳密に増加しています。元の問題のケースでは、同様のシーケンス番号IDが使用されていました。幸運にも、どちらの場合も、限られた範囲に修正するのは簡単です。上記テストコードについて

++数えます。 if(count> 1000)count = 0;

0

私のJava Swing days(ええ、私は昔です)に戻ると、JVMはやや似た問題を抱えていました。そのため、ガベージコレクタは、他のSwingオブジェクトの内部にネストされたSwingオブジェクトをクリーンアップできず、メモリリークが発生します。

私は、これを回避するために、各Swingオブジェクトを、もはや不要になったNULLに明示的に設定しました。

深くネストされたオブジェクト(つまり、他のSwingオブジェクトを含むスイングテーブル)の場合、すべてのSwingクラスで使用できる再帰的メソッドを書きました。このメソッドはSwingオブジェクトを横断して、内部にあるオブジェクト

JVMのガベージコレクタのバグを回避するために、このような余計な作業をしなくてはいけませんでしたが、うまくいきました。一度これを実行すると、メモリリークが消えてしまいました。

IE9と同様のものを試してみる価値があります。もはやDOMオブジェクトをNULLにする必要がなくなり、これを解決できます。そして私たちの残りの部分も同様に...-)

+0

ここでヒントを試しました(http://toranbillups.com/blog/archive/2009/04/21 /動的に生成されたDOM要素のIEでのクリーンアップ)、しかし役に立たない。私はまた、他の人がIE9が実際に古いIEバージョンでメモリリークの問題を解決すると言うことを聞いたことがあるので、これはIE9独自の新しいリークです。私が推測する新しいコードベース。 –