3

いくつかのDOMを作成してから削除する単純なhtml/javascriptコードがあります。

<!DOCTYPE html>
<html>

  <head lang="en">
    <meta charset="utf-8">
    <title>Custom Plunker</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  </head>

  <body>
    <button onclick="create()"> Create </button>
    <button onclick="clearContainer()"> Clear </button>

    <div id="container"></div>

  </body>

</html>

<script>
  function create() {
    var c = $("#container");
    for(var i = 0;i<10000; i++){
    c.append("<li>Hellosd fssd f df sdf  f f wef ewf we fwe f wef ewf wef ew few f ewf wf ewf wef </li>");
    }
  }

  function clearContainer() {
    var c = $("#container");
    c.empty();
  }
</script>

CreateボタンとボタンがありClearます。作成ボタンをクリックすると、コンテナdivに10000li要素が追加され、クリアボタンをクリックすると、それらが削除されます。

Chromeで試してみると、Chromeプロセスの初期メモリ使用量は約30Mですが、作成ボタンを数回クリックすると70Mになり、クリアボタンをクリックすると50Mになります。初期値より20M多いです。

次に、IE8で試してみます。IEプロセスの初期メモリ使用量は約30Mですが、作成ボタンを1回クリックすると、100M以上になり、クリアボタンをクリックすると80Mになります。初期値より50M多いです。

コードにメモリリークがありますか?それを修正する方法は?

4

2 に答える 2

7

コードにメモリリークがありますか?

いいえ。ブラウザは、再利用が必要な場合や、参照されなくなったオブジェクトを(まだ)ガベージコレクションしていない場合に備えて、割り当てたメモリの一部を保持しているだけです。リストアイテム要素へのすべての参照を(jQueryのempty呼び出しを介して)解放したので、実際にそれらを解放するのはブラウザーに任されています。

もちろん、この回答は、呼び出しているjQuery関数にメモリリーク(特にli要素を作成する関数)を引き起こすバグがないことを前提としています。もちろん、それはおそらく合理的な仮定ですが、もちろん、尊敬されているライブラリでさえエラーが発生することがあります。jQueryの一般的な関数の1つ(要素の構築を含む)に特定のバージョンで重大なメモリリークがある場合、ライブラリを使用している人の数と背後にいる従事しているチームを考えると、妥当な時間内に検出、報告、修正される可能性がありますそれ。

また、ブラウザのDOM操作の処理にバグがなく、メモリリークが発生することも想定されていますが、これはそれほど確実ではありません。(これまで、[フレーバーに関係なく]ブラウザーには、メモリリークに関するあらゆる種類の問題がありました。どのブラウザーも、影響を受けていないと思います。)

しかし、私が言っていることを理解していれば、コードにリークはありません。

于 2013-03-09T15:43:14.313 に答える
4

Chromium / linuxでテストすることにより、リークを確実に再現します。作成/クリアサイクルごとに、メモリが5MBから10 MBに増加し、このメモリは解放されていないようです。

clear関数を少し変更して、親要素を空にする代わりに置き換えることで、リークを回避できることに気付きました。

  function clearContainer() {
    var c = $("#container");
    c.remove();
    $('<ul id="container"></ul>').appendTo(document.body);
  }

このコードを使用すると、作成/クリアの各サイクルの後にメモリが同じレベルに戻ります。

問題はjQueryにあるとは思いませんが、Firefoxには同じ問題がないように思われるため、おそらくブラウザのDOMオブジェクトにあります。


編集

テストを自動化してさらにプッシュすることで、メモリが最終的に減少するのを確認できました(タブの約150 MBを超えた後、70 MBに戻る可能性があります)。ここでのメモリの管理方法は明らかに貪欲ですが、実際のメモリリークはありません。メモリ消費量は大きく異なる可能性があるため、親要素をクリアするのではなく削除することをお勧めしますが、メモリクラッシュが発生する可能性は低いと思われるため、クラッシュを防ぐことはできません。

于 2013-03-09T15:56:12.373 に答える