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