1. システムにガベージ コレクションが必要な理由
文字列、オブジェクト、配列には固定サイズがないため、サイズがわかっている場合にのみ動的に割り当てることができます。JavaScript プログラムが文字列、配列、またはオブジェクトを作成するたびに、インタープリターはそのエンティティを格納するためにメモリを割り当てる必要があります。このようにメモリが動的に割り当てられている限り、再利用できるように最終的には解放する必要があります。そうしないと、JavaScript インタプリタがシステム内の利用可能なメモリをすべて消費し、システムがクラッシュする原因になります。
C/C++ とは異なり、JS には独自のガベージ コレクション メカニズム (ガベージ コレクション) があります。JavaScript インタプリタは、プログラムがオブジェクトを使用しなくなったことを検出でき、オブジェクトが役に立たないと判断すると、そのオブジェクトが不要になり、そのオブジェクトが占有しているメモリを解放できることがわかります。
第二に、ガベージコレクションの方法
クリアのマークを付け、参照をカウントします。
2.1 マークの除去
これは最も一般的なガベージ コレクション方法です。変数が環境に入ると、「環境に入る」とマークされます。論理的に言えば、環境に入る変数によって占有されているメモリは決して解放できず、変数によって占有されているメモリは環境に入ったメモリは決して解放されませんが、実行プロセスが対応する環境に入る限り、メモリは使用できます。環境を離れると、環境を離れるとマークされます。
ガベージ コレクターが実行されると、メモリに格納されているすべての変数にマークが付けられ (すべて追加されます)、環境変数内の変数と環境変数内の変数によって参照される変数が削除されます (マークの条件付き削除)。マークされたすべての変数、削除された変数は環境変数内でアクセスできないため削除され、最後にガベージ コレクターがメモリのクリア作業を完了し、それらの変数が占有しているメモリを再利用します。
2.2 参照カウント方法
もう 1 つのあまり一般的ではない方法は、参照カウント方式です。参照カウント方式とは、各値が参照される回数を意味します。変数が宣言され、参照型の値がその変数に割り当てられると、この値への参照の回数がオンになります。逆に、この値への参照を含む変数が別の値を取得すると、元の参照値の参照数が 1 減ります。この値の参照数が 0 の場合、その値にアクセスする方法がないことを意味します。この値により、占有されていたメモリが再利用され、ガベージ コレクタが再度実行されると、参照カウント 0 でこれらの値が解放されます。
ガベージコレクションの例
例えば:
var a="hello world"; var b="world";
var a=b;
//この時点で「hello world」が解除され、メモリが解放されます
2.3 参照カウント方式ではメモリリークが発生する
その理由は次のとおりです。
function problem() {
var objA = new Object(); var objB = new Object();
objA.someOtherObject = objB; objB.anotherObject = objA;
}
この例では、objA と objB はそれぞれのプロパティを通じて相互に参照します。この場合、2 つのオブジェクトの参照カウントは 2 です。参照カウントを使用する戦略では、関数の実行後、両方のオブジェクトがスコープを離れます。関数の実行完了後はカウントが0ではないため、このような相互参照が大量にあるとメモリリークが発生します。
特に DOM オブジェクトでは、次のような問題が発生しやすくなります。
var element=document.getElementById(’‘); var myObj=new Object();
myObj.element=element; element.someObject=myObj;
この方法では、ガベージ コレクション プロセスは発生しません。