web-dev-qa-db-ja.com

Javascriptおよびガベージコレクション

Javascriptがガベージコレクションを実行するタイミングを制御する方法はありますか?特定の時間にガベージコレクションを実行できるようにして、Webサイトの円滑な運用を確保したい

43
Ed Heal

Javascriptには明示的なメモリ管理がありません。いつクリーンアップするかを決めるのはブラウザです。ガベージコレクションの一時停止により、JavaScriptのレンダリングがスムーズに行われない場合があります。

ガベージコレクション(GC)によって引き起こされるグリッチを克服するために適用できる多くのテクニックがあります。あなたが探求するほど、あなたはより多くを適用します。 JavaScriptで記述されたゲームがあり、毎秒新しいオブジェクトを作成していると仮定すると、一定の時間が経過するとGCが発生し、アプリケーション用のスペースがさらに確保されます。

多くのスペースを必要とするゲームのようなリアルタイムアプリケーションの場合、できる最も簡単なことは同じメモリを再利用することです。コードの構造によって異なります。大量のガベージが生成される場合は、途切れ途切れの経験になる可能性があります。

簡単な手順を使用して:これは、新しいキーワードが割り当てを示すことをよく知っています。可能な限り、プロパティを追加または変更することにより、毎回同じオブジェクトを再利用することができます。これはオブジェクトのリサイクルとも呼ばれます

配列の場合、配列をクリアするために[]の割り当てがよく使用されますが、新しい配列を作成し、古い配列を破棄することにも留意してください。同じブロックを再利用するには、arr.length = 0を使用する必要があります。これは同じ効果がありますが、新しい配列オブジェクトを作成する代わりに同じ配列オブジェクトを再利用します。

関数の場合:プログラムは、setIntervalまたはsetTimeoutを使用して、特定の関数をより多くの時間または特定の間隔で呼び出す必要がある場合がありました。

ex: setTimeout(function() { doSomething() }, 10);

上記のコードは、毎回定期的に生成するのではなく、関数を永続変数に割り当てることで最適化できます。

    ex : var myfunc = function() { doSomething() }
    setTimeout(myfunc, 10);

他に考えられることは、配列slice()メソッドが元の配列の範囲に基づいて新しい配列を返し(元の配列の範囲をそのまま使用できる)、文字列のsubstrも新しい文字列を返します(元の文字列の文字の範囲に基づいて、それはそのままでかまいません)など。これらの関数を呼び出すと、適切に再利用されないとガベージが作成されます。

JavaScriptでゴミを完全に回避することは非常に難しく、不可能と言えます。それは、ゴミを避けるためにオブジェクトと変数をどのように再利用するかによります。コードが適切に構造化および最適化されている場合、オーバーヘッドを最小限に抑えることができます。

75
Shadow

残念なことに、ガベージコレクションが行われるときを制御する方法はありませんが、オブジェクトを適切に形成することで、それがどれだけ迅速かつクリーンに発生するかを制御できます。 Mozilla Dev Netのこれらのドキュメント をご覧ください。

このアルゴリズムは、ルートと呼ばれる一連のオブジェクトの知識を前提としています(JavaScriptでは、ルートはグローバルオブジェクトです)。定期的に、ガベージコレクターはこれらのルートから開始し、これらのルートから参照されるすべてのオブジェクトを検索し、次にこれらから参照されるすべてのオブジェクトなどを検索します。到達可能なオブジェクト。

「オブジェクトの参照がゼロ」のため、このオブジェクトは到達不能になるため、このアルゴリズムは前のアルゴリズムよりも優れています。サイクルで見たように、逆は真実ではありません。

5
DevlshOne

オブジェクトをGCするまで、すべてのオブジェクトへの参照を保持しませんか?

var delayed_gc_objects = [];
function delayGC(obj) { // keeps reference alive
    return delayed_gc_objects[delayed_gc_objects.length] = obj;
}
function resumeGC() { // kills references, letting them be GCd
    delayed_gc_objects.length = 0;
}
2
Paul S.

次のようないくつかの変更を実行して、メモリ使用量を改善できます。

  1. ループに変数を設定しないでください
  2. グローバル変数と関数の使用を避けてください。あなたが出るまで、彼らはメモリの一部を取ります
0
Jean Carlos

JavaScriptはガベージコレクションされた言語です。つまり、実行環境はコード実行中に必要なメモリの管理を担当します。 JavaScriptのガベージコレクションの最も一般的な形式は、マークアンドスイープと呼ばれます。 2番目に人気の低いタイプのガベージコレクションは、参照カウントです。アイデアは、すべての値がそれに対して行われた参照の数を追跡するということです

GCはこれらのアルゴリズムに従います。GCをトリガーしたとしても、すぐに実行されることは保証されません。マークするだけです

0
anish