1

簡単な質問です。ガベージ コレクターにとってどちらが優れているか:

  • オブジェクトを配列に追加し、null を配列 cell に代入する

this.requests[i] = new NiceClass();

this.requests[i] = null;

  • 単純な変数を作成し、この変数に null を割り当てます

var niceClass = new NiceClass();

niceClass = null;

配列の使用を避けたいので質問しています。多くのオブジェクトを作成している間-オブジェクトへの参照を壊しているにもかかわらず、ガベージコレクターが不要なオブジェクトを取得できるようになっているため-配列が成長しているため、ここで必要なのか、それとも必要なのか変数だけを使用する方がさらに良いでしょうか?

4

1 に答える 1

2

あなたが忘れているいくつかのこと:

JS の GC の動作方法は実装によって異なります。V8 はメモリを適切に管理しますが、古いバージョンの IE ではさびた水切り以上のリークが発生しました。
ただし、変数を null に設定しても初期化されません。他の言語の とは異なります (コンソールに入力してみNullてください)。代わりに試してください。それでも、Jsには予約済みのキーワードがあり、それはあなたが求めているものだと思われます。全体として、オブジェクトが変数または配列によって参照されている場合、それは問題ではありません。注:グローバル スコープで変数を削除すると、常にnulltypeof nullsomeVar = undefineddelete
delete someArray[i];delete someVar;
true を返しますが、その変数が (varキーワードを使用して) 明示的に宣言されているか、関数である場合は削除されません。暗黙のグローバルのみを削除できるため、次のようになります。

var global1 = 'I cannot be deleted';
function global2()
{
    global3 = 123;//implied global
}
global4 = function()
{
    console.log('implied global function, can be deleted');
};
delete global1;//returns true
console.log(global1);//I cannot be deleted
delete global2;
global2();//shouldn't create global3, because it was deleted but:
console.log(global3);//123
delete global3;//true
console.log(global3);//undefined, was deleted
delete global4;//true
global4();//error <--- was deleted = reference error

ただし、どちらの場合も、スクリプト内のどこかのクロージャまたは別の変数によって参照されているオブジェクトを逆参照しても、GC it は実行されません
一般に、JS GC はサイクルでメモリにフラグを立ててスワイプするだけです。特定のオブジェクトへのすべての参照がスコープ外になると、フラグが付けられ、メモリの割り当てが解除されます。このプロセスを実際に制御することはできないため、コードを実際に最適化することはできません。

それでも、FF または Chrome でタイムライン ツールとプロファイラー ツールを使用したい場合は、私のゲストになってください。ただし、覚えておいてください: 特定の JS エンジン向けに最適化しているのは、それを行っているときです: V8 に最適化されたコードは、Chrome と Safari でよりクリーンなメモリを生成する可能性がありますが、ご存知のとおり、IE は物事の完全なハッシュを作成する可能性があります。または、使用したいくつかのトリックにより、FF が遅くなり、かなり大きな配列が最初に行ったよりも遅くなります。
この暴言はここでやめようと思います... 結論: 実際に制御できないものを最適化することはできません。

アップデート:

現在発生しているメモリリークについてのコメントを読んだばかりなので、変数をnullorundefinedまたはdelete-ing に設定しても、あまり効果がないと思います。(最新の) GC が確実に機能するようにするためのはるかに優れた方法は、クロージャーを巧妙に使用することです。それらの変数が返される場合、またはその関数の戻り値がそれらの変数を参照するオブジェクトまたは別の関数のいずれかである場合、それらは GC されませんが、参照されなくなった変数は割り当て解除されます。
グローバル変数がスコープ外になることはないため、 GC されることはありません。それがグローバルが悪い理由です. 最適化する JS コードが本当にたくさんある場合は、IIFE に何かを入れ始めると、わずかな労力で大きな違いが生まれる可能性があります。

于 2012-10-28T16:50:49.470 に答える