JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

クロージャによるメモリリークの原因と防止方法をわかりやすく解説


クロージャとは

JavaScriptの強力な機能のひとつが「クロージャ」です。JavaScriptでは関数の中に関数をネストして定義でき、内側の関数から外側の関数の変数へアクセスすることができます。このように、内側の関数が外側の関数の変数にアクセスする仕組みをクロージャと呼びます。

メモリリークは、宣言された変数が自動的に内側のネストされた関数から参照可能になった結果、たとえその関数内で実際には使用されていなくてもメモリ上に残り続けることで発生します。

以下の例では、「childFunction」が外側の関数「parentFunction」の中で定義された内側の関数です。「parentFunction」を引数"outer val"で呼び出すと、外側の変数aには"outer val"という値が代入されます。そしてこの関数は、内側の関数「childFunction」へのポインタを返し、それが変数valに格納されます。

注目すべきは、外側の関数がreturnした後でも、そのローカル変数aは存在し続けるという点です。JavaScriptでは、parentFunctionが呼び出された瞬間に、プロパティ'a'を持つスコープオブジェクトが生成されます。このプロパティには引数arg1の値、つまり"outer val"が保持されます。同様に、parentFunctionが値を返す際には、変数valに格納された内側の関数(childFunction)が返されます。

内側の関数が外側の関数の変数への参照を保持し続けているため、プロパティ'a'を持つスコープオブジェクトはガベージコレクションによって回収されません。これがメモリリークにつながる仕組みです。

サンプルコード

<html>
<body>
<script>
    window.onload= function parentFunction(arg1) {
        var a = arg1;
        return function childFunction (arg2)
    {
        alert( a +" "+ arg2);
    };
    };
    var val = parentFunction("outer val");
    val("inner val");
</script>
</body>
</html>

メモリリークを防ぐ方法

関数をもう1つ追加する

もう1つ関数を追加することで、内側の関数が2つになります。内側の関数が2つ存在すると、どちらの関数も外側の関数の変数を直接参照できなくなるため、クロージャ自体が成立しなくなります。

クロージャが発生しなければ、メモリリークが起こる可能性も大幅に低くなります。

サンプルコード

<html>
<body>
<script>
    window.onload=function parentFunction(){
        var Obj1 = function childFunction1()
        {
            document.write("メモリリークは回避されました");
        };
    (function childFunction2(){
        var obj2 = document.getElementById("closure");
        obj2.onclick=Obj1
        })();
    };
</script>
<input type = "button" id="closure" value ="クリックしてください">
</body>
</html>

このコードを実行すると、次のようなボタンが表示されます。

クロージャによるメモリリークの原因と防止方法をわかりやすく解説

ボタンを押すと、次のような出力が得られます。

実行結果

メモリリークは回避されました
  1. DNSリークとは?主な原因と効果的な防止・確認方法を徹底解説

    リモートアクセスの普及に伴い、ハッキングの手口は年々巧妙化しています。公共Wi-Fiの拡大も、ISP(インターネットサービスプロバイダ)が提供する接続に深刻な脆弱性をもたらしました。さらに、個人PCや企業ネットワークへのサイバー攻撃やランサムウェア攻撃が増加する中、ネット空間に保存されるデータの機密性と安全性が改めて問われています。現在、攻撃者はシステムそのものに侵入しなくても、インターネット回線への侵入だけで、ユーザーを悪意のあるサイトへ誘導し、システムやブラウザ全体の活動に感染させることが可能になっています。こうした攻撃手法の一つが「DNSリーク(DNS漏えい)」です。本記事では、DNSリ

  2. スパイウェア・アドウェアの感染を防ぐには?原因と対策を徹底解説

    スパイウェアやアドウェアに感染していないパソコンを維持することは、現代において個人の責任であり必須事項となっています。サイバー犯罪者は日々巧妙化しており、ウイルス、キーロガー、スパイウェア、アドウェア、悪意のあるリンクなどを送り付け、金銭的な利益のために機密情報を狙っています。幸いにも、いくつかの対策を実践するだけで、これらの感染を防ぐことが可能です。対策に入る前に、まずは「スパイウェア」「アドウェア」とは何かを理解しておきましょう。 スパイウェアとは? スパイウェアとは、攻撃者がユーザーの知らない間にコンピューターへ侵入させることを目的として作られたソフトウェアです。多くの場合、インターネッ