クロージャーはメモリリークを引き起こすのでしょうか?
前書き
メモリ リークの問題について話す前に、JavaScript のガベージ コレクション メカニズムを見てみましょう。JavaScript には、使用されなくなった変数を見つけて、それらが占有しているメモリを解放する自動ガベージ コレクション メカニズムがあります。これを行うために、ガベージ コレクターは一定の間隔 (またはコード実行中にスケジュールされた収集時間) で動作します。一般的に使用される方法には、クリア マーキングと参照カウントの 2 つがあります。
1. マーク スイープ
JavaScript で最も一般的に使用されるガベージ コレクション方法は、マーク アンド スイープです。ガベージ コレクターは、実行時にメモリに格納されているすべての変数にマークを付けます (任意のマーク方法を使用できます)。次に、環境内の変数と環境内の変数によって参照される変数のタグを削除します。これ以降にマークされた変数は、環境内の変数がこれらの変数にアクセスできなくなるため、削除される変数とみなされます。最後に、ガベージ コレクターはメモリのクリーンアップ作業を完了し、マークされた値を破棄し、それらが占有しているメモリ領域を再利用します。
2. 参照カウント
参照カウントの意味は、各値が参照された回数を追跡することです。変数が宣言され、その変数に参照型の値が割り当てられている場合、この値への参照の数は 1 です。同じ値が別の変数に代入されている場合、その値の参照カウントは 1 増加します。逆に、この値への参照を含む変数が別の値を取得すると、この値への参照の数は 1 つ減ります。この値への参照の数が 0 になると、この値にアクセスする方法がなくなったことを意味するため、この値が占有しているメモリ領域を再利用できます。こうすることで、次回ガベージ コレクターが実行されるときに、参照がゼロの値によって占められていたメモリが解放されます。
Netscape Navigator 3.0 は、参照カウント戦略を使用した最初のブラウザでしたが、すぐに深刻な問題に遭遇しました。次の例を参照してください:
function problem(){ var objectA = new Object(); var objectB = new Object(); objectA.someOtherObject = objectB; objectB.anotherObject = objectA; }
説明: objectA と objectB は、それぞれの属性、つまり、両方のオブジェクトの参照カウントは 2 です。マーク アンド スイープ戦略を使用する実装では、関数の実行後に両方のオブジェクトがスコープを離れるため、この相互参照は問題になりません。ただし、参照カウント戦略を使用した実装では、objectA と objectB の参照数が 0 になることはないため、関数の実行後も存在し続けます。この関数が複数回呼び出された場合、大量のメモリはリサイクルされません。
このため、Netscape は Navigator 4.0 で参照カウント方式を放棄しましたが、参照カウントによって引き起こされる問題はこれで終わりではありませんでした。 IE 9 より前の一部のオブジェクトはネイティブ JavaScript オブジェクトではありませんでした。たとえば、BOM および DOM 内のオブジェクトは、C++ を使用して COM (コンポーネント オブジェクト モデル) オブジェクトの形式で実装され、COM オブジェクトのガベージ コレクション メカニズムでは参照カウント方式が使用されます。したがって、IE の JavaScript エンジンはマーク アンド スイープ戦略を使用して実装されていますが、JavaScript によってアクセスされる COM オブジェクトは依然として参照カウント戦略に基づいています。言い換えれば、COM オブジェクトが IE に関与する場合は常に、循環参照の問題が発生します。
例:
var element = document.getElementById("some_element"); var myObject = new Object(); myObject.element = element; element.someObject = myObject;
DOM 要素 (element) とネイティブ JavaScript オブジェクト (myObject) の間に循環参照が作成されます。その中で、変数 myObject には要素オブジェクトを指す element という名前のプロパティがあり、変数 element には myObject を指す someObject という名前のプロパティもあります。この循環参照のため、例の DOM がページから削除されても、リサイクルされることはありません。
解決策: 変数を null に設定して、変数と以前に参照していた値の間の接続を切断します。
myObject.element = null; element.someObject = null;
上記の内容を読んだ上で、本題についてお話しさせていただきます。
クロージャーによってメモリ リークが発生することはありません
IE9 より前のバージョンでは、JScript オブジェクトと COM オブジェクトに対して異なるガベージ コレクションが使用されるためです。したがって、これらのバージョンの IE では、クロージャによっていくつかの特別な問題が発生します。具体的には、HTML 要素がクロージャのスコープ チェーンに格納されている場合、その要素は破棄できないことを意味します。例を参照してください。
function assignHandler(){ var element = document.getElementById("someElement"); element.onclick = function(){ alert(element.id); }; }
上記のコードは、要素要素のイベント ハンドラとして機能するクロージャを作成します。このクロージャーは循環参照を作成します。無名関数は assignHandler() のアクティブなオブジェクトへの参照を保存するため、要素への参照の数を減らすことができなくなります。匿名関数が存在する限り、要素の参照番号は少なくとも 1 であるため、要素が占有するメモリは決してリサイクルされません
解決策は序文で述べたように、element.id のコピーを変数に保存することで、削除 クロージャ内の変数への循環参照も、要素変数を null に設定します。
function assignHandler(){ var element = document.getElementById("someElement"); var id = element.id; element.onclick = function(){ alert(id); }; element = null; }
概要: クロージャはメモリ リークを引き起こしませんが、IE9 より前のバージョンでは JScript オブジェクトと COM オブジェクトに対して異なるガベージ コレクションが使用されるため、メモリをリサイクルできません。これは IE の問題であるため、クロージャとメモリ リークは問題ではありません。 。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

エントリーレベルのタイプスクリプトチュートリアルをマスターしたら、TypeScriptをサポートするIDEで独自のコードを作成し、JavaScriptにコンパイルできるはずです。このチュートリアルは、TypeScriptのさまざまなデータ型に飛び込みます。 JavaScriptには、NULL、未定義、ブール値、数字、文字列、シンボル(ES6によって導入)とオブジェクトの7つのデータ型があります。 TypeScriptはこれに基づいてより多くのタイプを定義し、このチュートリアルではすべてを詳細に説明します。 ヌルデータ型 JavaScriptのように、Typescriptのnull

JavaScriptはPowerPointで実行でき、外部JavaScriptファイルを呼び出したり、VBAを介してHTMLファイルを埋め込んだりすることで実装できます。 1. VBAを使用してJavaScriptファイルを呼び出すには、マクロを有効にし、VBAプログラミングの知識を持つ必要があります。 2。JavaScriptを含むHTMLファイルを埋め込みます。これは、シンプルで使いやすいが、セキュリティ制限の対象となります。利点には、拡張機能と柔軟性が含まれますが、欠点にはセキュリティ、互換性、複雑さが含まれます。実際には、セキュリティ、互換性、パフォーマンス、ユーザーエクスペリエンスに注意を払う必要があります。
