ホームページ > 記事 > ウェブフロントエンド > JavaScript のメモリ リークの原因は何ですか?
JavaScript メモリ リークの原因: 1. グローバル変数の不適切な使用; 2. クロージャの不適切な使用; 3. 遅延またはタイマーがクリアされていない; 4. クリアされていない DOM 要素参照 (dom Cleared または Theイベントは削除されてもクリアされません)。
このチュートリアルの動作環境: Windows7 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター。
メモリ リークとは、ブラウザのプロセスが終了するまで、割り当てられたメモリの一部が使用またはリサイクルできないことを意味します。これは、過失またはエラーにより、プログラムが使用されなくなったメモリを解放できなかったことを意味します。 メモリ リークとは、メモリの物理的な消失を指すのではなく、アプリケーションがメモリの特定のセグメントを割り当てた後、設計エラーにより、メモリのセグメントの制御がメモリのセグメントよりも先に失われるという事実を指します。メモリが解放されるため、メモリ破損が発生します。メモリ リークの一般的な原因をいくつか示します。
JavaScript は未宣言の変数を処理できます: 未宣言の変数への参照により、グローバル オブジェクトに新しい変数が作成されます。ブラウザのコンテキストでは、グローバル オブジェクトはウィンドウです。
function foo(){ name = '前端曰'; } // 其实是把name变量挂载在window对象上 function foo(){ window.name = '前端曰'; } // 又或者 function foo(){ this.name = '前端曰'; } foo() // 其实这里的this就是指向的window对象
このように、予期しないグローバル変数が意図せず作成されます。このエラーが発生しないようにするには、JavaScript ファイルの先頭に「use strict;」を追加します。これにより、予期しないグローバルを防ぐ、より厳密な JavaScript 解析モードが有効になります。または、変数の定義に自分で注意してください。
クロージャ: 匿名関数は親スコープ内の変数にアクセスできます。
var names = (function(){ var name = 'js-say'; return function(){ console.log(name); } })()
クロージングにより、オブジェクト参照のライフサイクルが現在の関数のコンテキストから分離されます。クロージャが不適切に使用されると、次のような循環参照 (循環参照) が発生する可能性があります。デッドロックは回避することしかできず、発生後に解決することはできません。ガベージ コレクションを使用してもメモリ リークは発生します。
日常のニーズで、setInterval/setTimeout を試すことがよくありますが、使用後にクリーンアップすることを忘れてしまいます。
var someResource = getData(); setInterval(function() { var node = document.getElementById('Node'); if(node) { // 处理 node 和 someResource node.innerHTML = JSON.stringify(someResource)); } }, 1000);
setInterval/setTimeout の This は window オブジェクトを指しているため、内部定義された変数もグローバルにマウントされます。someResource 変数は if で参照され、setInterval/setTimeout がクリアされていない場合、someResource は実行されません。 ;同様に、setTimeout についても同じことが当てはまります。したがって、終了時には忘れずにclearInterval/clearTimeoutを行う必要があります。
var elements = { button: document.getElementById('button'), image: document.getElementById('image'), text: document.getElementById('text') }; function doStuff() { image.src = 'http://some.url/image'; button.click(); console.log(text.innerHTML); } function removeButton() { document.body.removeChild(document.getElementById('button')); // 此时,仍旧存在一个全局的 #button 的引用 // elements 字典。button 元素仍旧在内存中,不能被 GC 回收。 }
[推奨される学習: JavaScript 上級チュートリアル ]
以上がJavaScript のメモリ リークの原因は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。