はじめに
C などの低レベル言語には、malloc() や free() などの低レベルのメモリ管理コマンドがあり、開発者は手動でメモリを解放する必要があります。ただし、JavaScript などの高級言語では状況が異なります。オブジェクト (オブジェクト、文字列など) は作成時にメモリを割り当て、使用されなくなったメモリは自動的にリサイクルされます。この自動リサイクルプロセスはガベージコレクションと呼ばれます。 JavaScript などの高級言語の開発者は、ガベージ コレクションの存在により、メモリ管理を気にする必要がないと誤解しています。
メモリのライフサイクル
どのようなプログラミング言語であっても、メモリのライフサイクルは基本的に同じです。
1. 必要なメモリを割り当てます
2. 読み取りおよび書き込み操作に使用します
3. メモリが不要になったらリソースを解放します
ステップ 1 と 2 はすべての言語で同じであり、明確に気づくことができます。ステップ 3 に関しては、低レベル言語では開発者がこれを明示的に実行する必要があります。 JavaScript のような高水準言語の場合、操作のこの部分はパーサーによって実行されるため、気付かれることはありません。
JavaScript での代入操作
値の初期化
変数に値を代入すると、JavaScript によってメモリの割り当てが完了します。
いくつかの関数が実行された後、オブジェクトの割り当ても行われます。
値の使用は、実際には、割り当てられたメモリ上で読み取りおよび書き込み操作を実行することです。これらの操作には、変数またはオブジェクト プロパティに対する読み取りおよび書き込み操作、または関数へのパラメーターの受け渡しが含まれます。
不要になったらメモリを解放します
メモリ管理の問題のほとんどはこの段階で発生します。最も難しいのは、割り当てられたメモリがいつ不要になるかを判断する方法です。このため、開発者は多くの場合、プログラムがメモリを必要としなくなった時期を判断し、メモリが占有しているリソースを解放する必要があります。
「ガベージ コレクター」と呼ばれるプログラムは、高級言語パーサーに組み込まれており、メモリの割り当てと使用状況を追跡し、メモリが必要かどうかを判断し、メモリが不要になった場合はリソースの解放操作を実行します。必要です。メモリが必要かどうかの判断は不確実な問題である (アルゴリズムでは解決できない) ため、彼は近似値を取得することしかできません。
ガベージコレクション
上で述べたように、「メモリが不要になった」と正確かつ自動的に判断することはできません。したがって、この問題の解決策としてガベージ コレクションには限界があります。このセクションでは、主要なガベージ コレクション アルゴリズムとその制限事項を理解するために必要な概念について説明します。
引用
ガベージ コレクションの主要な概念は参照です。メモリ管理では、オブジェクトが明示的または暗黙的に別のオブジェクトを使用することを、そのオブジェクトが別のオブジェクトを参照すると言います。たとえば、JavaScript オブジェクトには、そのプロトタイプへの暗黙的な参照と、そのプロパティ値への明示的な参照があります。
ここでのオブジェクトの概念は、JavaScript における従来のオブジェクトの概念を超えており、関数スコープとグローバル スコープも含まれています。
参照カウント アルゴリズムを使用したガベージ コレクション
以下に紹介するのは、「オブジェクトが不要になった」、「他のオブジェクトがそのオブジェクトを参照しない」という概念を導入した最適なアルゴリズムです。オブジェクトの参照ポインタが 0 になると、リサイクルの準備ができたとみなされます。
例:
oa = null; // これで属性 a は他のオブジェクトから参照されなくなり、オブジェクトはリサイクルできるようになります
このアルゴリズムには制限があります。オブジェクトが別のオブジェクトを参照し、循環参照が形成されると、それらが不要になった場合でも、ガベージ コレクターはそれらを再利用しません。
彼は、「不要になったオブジェクト」と「到達不能なオブジェクト(オブジェクト到達不能)」という概念を導入しました。このアルゴリズムは、一連のルート オブジェクトが存在することを前提としています (JavaScript のルート オブジェクトはグローバル オブジェクトです)。ガベージ コレクターはルート オブジェクトから開始し、参照するすべてのオブジェクトを走査し、次に、ルート オブジェクトを走査します。参照オブジェクトによって参照されるオブジェクトなど。このアプローチを使用すると、ガベージ コレクターはアクセス可能なすべてのオブジェクトを取得し、アクセスできないオブジェクトを再利用できます。
このアルゴリズムは、0 によって参照されるオブジェクトがアクセス不可能なオブジェクトとして設定されると同時に、循環参照によって引き起こされる問題も回避します。
2012 年現在、ほとんどの最新ブラウザはこの「マーク アンド スイープ」ガベージ コレクターを使用しています。 JavaScript のガベージ コレクション (世代別/増分/同時/並列ガベージ コレクション) の分野は、ここ数年でそれに関連するアルゴリズムが改良されてきましたが、ガベージ コレクションのアルゴリズムそのもの (マークスイープ アルゴリズム) や「オブジェクトかどうかを判断する方法」は、はもう必要ありません」は改善されていません。
生理周期はもう問題ではありません
最初の例では、関数呼び出しが終了すると、これら 2 つのオブジェクトはグローバル オブジェクトによって参照されなくなり、グローバル オブジェクトによって参照されるオブジェクトからも参照されなくなります。したがって、これらは JavaScript ガベージ コレクターによってアクセス不可能なオブジェクトとしてマークされます。 2 番目の例でも同じことが起こり、div とイベント ハンドラーがガベージ コレクターによってアクセス不能としてマークされると、それらは解放されます。
制限事項: オブジェクトは明示的にアクセス不可としてマークする必要があります
このマーキング方法には制限がありますが、プログラミングでこの方法に触れたことがないため、ガベージ コレクション関連のコンテンツについてはほとんど気にしません。