2011-12-06 30 views
3

私はjavascriptを初めて使い、メモリリークを追跡するのに少し問題があるようです。私は、コードがかなり複雑であるため、メモリリークの原因と思われるセクションに絞り込んだ。私はそれを単純化するが、同じ問題(ちょっとだけ小さい)を引き起こす別の例を投稿します。現在のブラウザでクロージャと(jQuery)DOMイベントのメモリリークが発生しましたか?

Code Example

基本的に、私は動的にHTMLを構築し、HTMLにイベントをアタッチいくつかのコードを持っています。 HTMLはすべてのAJAXリクエストで再構築されます。これはすべてうまく動作し、初心者ですが、各AJAXリクエストの後にブラウザのメモリが上昇します(必ずしも等しいとは限りません)!この問題は、jsfiddleで複数回実行をクリックし、ブラウザのメモリを見て再現することができます。私の前提は、作成されるクロージャーは決してガベージコレクションされませんが、わかりません。それが問題ではない閉鎖なしでこれを行うより良い方法があるのならば?

これは、FF8、Chromeの最新バージョン、およびIE 8で発生します。ほとんどの場合、他のすべての可能性があります。

コードにいくつかコメントを入れておきます。

ありがとうございます!

EDIT: [OK]を、篩を用いていくつかのより多くの研究を行った後、私は、DOMの数のノードは、すべてのAJAX呼び出しで倍増していることを確認できるように。これをシミュレートするサンプルを更新しました。だから私の質問はなぜjQueryを空にしたり関数を削除した後にDOM要素がガベージコレクションされないのですか?私も...イベントハンドラのバインドを解除し、影響を与えずにnullに各DOM要素jsの参照を設定するもので要素を

Code Example

+0

IE6などでいくつかのHTML/DOM-JSメモリの問題がありました(DOMに1つのメモリモデルがあり、JSエンジンが別のものを持っていて2つの間で解決しようとしていました)。現代のブラウザーに現在の "落書き"があるかどうかは分かりません。 –

+0

最新のChromeでこれを再現することはできません:/ –

+0

Chromeの「最新バージョン」は常に同じとは限りません。また、使用するjQueryのバージョンも指定します。 :) [旧バージョンのjQueryにはイベントによるメモリリークがありました。](http://bugs.jquery.com/ticket/5285) –

答えて

1

をループしましたこれは、メモリを割り当てるためのプログラムのために珍しいことではありません、その参照メモリ使用量が増えて、そのメモリが解放されると変更されません。これは、基盤となるOSがメモリを管理していることの結果であり、必ずしも "問題"ではなく、必ずしも心配する必要はありません。全体的なプロセス統計を追跡するシステムツールに頼るのではなく、一般的に、他のツールを使用してプログラム内のメモリリークを特定する必要があります(ネイティブコードであろうとブラウザーでのライブであろうと)。

0

ブラウザのメモリ使用量を調べるだけで十分です。それをより正確にテストするには、コードを何回も実行してから、ブラウザのメモリ使用量を確認し、さらに多くの時間を実行して新しい数を比較します。

通常、ブラウザはのように振る舞いません。ちょうどのJavaScriptを使用します。したがって、コードの漏洩がなくてもメモリ使用量が変動する可能性があります。

0

少なくともIEではメモリリークを減らしたり避けたりするトリックがありました。

メモリが現在の方法より速く解放されているかどうかを調べることができます。
最初にHTMLをDOMに挿入し、イベントを添付します。

0

私はShaggyFrogとなっています。ローカル変数を削除してメモリ割り当てを減らし、完了したら配列appendUsを手動で空にすることができます。 Chromeでは、スクリプトの実行ごとにメモリ割り当てが800KB〜1MBずつ増加することがわかりました。上記のようにsmall changes to your codeを作成すると、追加のメモリ割り当てが各実​​行で400〜500KBに削減されました(平均で、タスクマネージャを手動で観察)。

これは、WindowsやChrome、メモリ管理のようなものだと言えます。しばらくの間JSFiddleページをアイドル状態にした後、Chromeのメモリ使用量は、サンプルを実行する前の状態に戻りました。ガベージコレクションのいくつかの種類が最終的に起こった、ちょうどそれが起こることを期待しているようにすぐにではないかもしれません。

3

これはDOMのGCとJavaScript GCが友人ではないことと関係があります。基本的な要点は、もし何かがDOMによって参照されると、JS GCはそれを破壊しない可能性があり、その逆もあります。このアイデアは時代遅れかもしれません。ブラウザの古い世代であるCrockfordの本に登場します。

私はJSフィドルに固有のかもしれないができない可能性があります、ここではいくつかの潜在的な問題を参照してください。

  • はFを割り当てることが必要ですか?
  • あなたがここにDOM要素のLOT一つずつを作成している
  • あなたがしている各実行時にFを再作成するので、問題には、JavaScriptのGC
  • のJavaScriptのGCよりもDOMのGCでの可能性が高いですそれは "怠け者"であることを意味するマークアンドスイープスキャナです。これをスクリプトで見ることができます。これを10回実行すると、メモリ使用率が非常に高くなりますが、最終的には放棄されたオブジェクトがガベージコレクションされ、メモリ使用量が低下します。
  • あなたが気にする必要があるクロージャは、click要素に割り当てられたクロージャですが、ここではクロージャを使用していません。

実際の問題はありませんが、数分後に私のメモリ使用量は正常に戻ります。

要するに、メモリリークはありません(少なくとも1つ以上)、JSインタプリタのGCはちょうど怠惰です。あなたは多くのDOM要素を放棄しています。これはうまくいかず、メモリが急増している理由ですが、それは長期的なページ読み込みの問題ではなく、短期間のパフォーマンスヒットです。

関連する問題