2009-09-23 19 views
7

私のアプリケーションでは、多数の大きなオブジェクトが一度に解放される特定の時間があります。当時、私は特にラージオブジェクトヒープ(LOH)でガベージコレクションを行いたいと思います。GC。第2世代および大型オブジェクトのヒープのみの収集

私はあなたがそれを行うことができないことに気付いています.にコールする必要があります。これは、GCが第2世代コレクションを実行しているときにLOHで呼び出されるためです。しかし、私はGC.Collect(2)はまだ世代の1と0の

でGCを実行します呼び出すと、それが唯一のはGEN 1またはGEN 0を含まGEN 2を収集し、ないにGCを強制することが可能であることを文書で読みました?

可能でない場合、そのようにGCを設計する理由はありますか?

+0

なぜあなたはこれをやりたいのですか?つまり、gen 0または1から収集しないでください。 .NET GCは、それ自身のデバイスに残すと最適に動作します。 – thecoop

+0

私はそれを認識しています。基本的には、集中的な操作であるため、手動でGCを強制的に実行する必要はありません。それ以来、GCを実行する必要があるときは、完全なGCを実行するのではなく、特定の世代に対してのみ実行したいと考えています。私はGCの使用についてより具体的にしようとしています。それは私に任せません。 – DevinB

答えて

12

これはできません。世代2のコレクションは常にも世代0と1

編集を収集するようにGCが設計されています:a GC developer's blogにあなたにこのソースを発見:

のGen2 GCがいっぱいコレクション (Gen0が必要です、Gen1、Gen2、およびLOH!Large オブジェクトは、GCが のLOHにスペースがないことによってトリガーされない場合でも、Gen2 GC ごとにGCされます。 オブジェクトのみを収集するGCではありません。 )これはよりもはるかに時間がかかります若い世代のコレクションは0個。

編集2:同じブログの使い方GCから効率的にPart 1Part 2唯一のGen2を行うことでもないだろうと私には合理的と思われるように、明らかにGen0とGen1のコレクションは、Gen2のコレクションに比べて高速であります多くのパフォーマンス上の利点。より根本的な理由があるかもしれませんが、わかりません。たぶん答えは、そのブログのいくつかの記事です。

+0

ありがとう!注意してください、私は私の質問を編集して、なぜこのように制約されているのか尋ねます。 – DevinB

6

すべての新しい割り当て(ラージオブジェクト以外)常にがGen0に入るため、GCは常に指定された世代以降のものを収集するように設計されています。 GC.Collect(2)に電話すると、Gen0、Gen1、Gen2から収集するようにGCに指示します。

大量のオブジェクト(割り当て時にLOH上に配置するのに十分な大きさのオブジェクト)を扱っていることが確実な場合は、それらをnull(VBではNothing)に設定することをお勧めします。あなたがそれらと一緒に完了したとき。 LOH割り当てはスマートでブロックの再利用を試みます。たとえば、LOHに1MBのオブジェクトを割り当てて廃棄し、それをnullに設定した場合、1MBの「穴」が残っています。次回、1MB またはそれより小さいサイズののLOH上に何かを割り当てると、それはその穴を埋めるでしょう(そして、次の割り当てが大きすぎて残りのスペースに収まらないうちにそれを埋めるでしょう。新しいブロックを割り当てます)。

.NETの世代は物理的なものではありませんが、GCのパフォーマンスを向上させる論理的な分離です。新しい割り当てはすべてGen0に入っているので、それは常に収集される最初の世代です。実行される各収集サイクルでは、収集を生き延びた低い世代のものは次の世代に「昇格」されます(Gen2に達するまで)。

ほとんどの場合、GCはGen0の収集を超える必要はありません。GCの現在の実装はGen0とGen1を同時に収集できますが、Gen0またはGen1が収集されている間はGen2を収集できません。 (.NET 4.0ではこの制約が大幅に緩和され、ほとんどの場合、Gen0またはGen1も収集されている間にGCはGen2を収集することができます)。

+0

あなたの説明は、GCがどのように機能するかの概要ですが、厳密に* gen 1またはgen 2コレクションを排除する制約がある理由を明確にしていません。 – DevinB

+2

'myVar = null'を設定しても何も成立しません。 http://www.bryancook.net/2008/05/net-garbage-collection-behavior-forの下部を参照してください。html – DevinB

+0

私は、高次の世代にオブジェクトを宣伝することは、GC中にのみ評価され(影響を受けて)いると考えているため、おそらく低世代を収集しない場合は何もしないでしょう... –

0

「なぜ」:物理的には、 Gen0とGen1またはGen2のようなもの。それらはすべて仮想アドレス空間上で同じメモリブロックを使用します。それらの間の区別は、仮想的な境界の限界の周りを移動することによってのみ実際に行われます。

すべての(小さな)オブジェクトは、Gen0ヒープ領域から割り当てられます。収集後、それが存続する場合、管理されたヒープブロックのその領域に「下向きに」移動され、最終的にはガベージから解放されました。これは、ヒープを圧縮することによって行われます。完全なコレクションが終了した後、Gen1の新しい境界線は、それらの生き残ったオブジェクトの直後のスペースに設定されます。

Gen0および/またはGen1を消去するだけの場合は、「完全な」ヒープ(Gen0のオブジェクトも含む)を圧縮して閉じる必要があるヒープに穴を開けることになります。これらのオブジェクトの大部分はとにかくゴミになるので、明らかにこれはどんな意味も持たないでしょう。それらを動かすことには何の意味もありません。また、ヒープを作成したり、ヒープを大きくしたりする必要もありません。

+0

概念的には、 Gen2のことをヒープの底に、Gen1はすぐ上に、Gen0はまさに上にあると考えることができます。古いオブジェクトは常に若いオブジェクトの下にあります。コンパクションが発生すると、システムは最も古いオブジェクトから始めて、圧縮される世代のすべてのライブオブジェクトを通過し、各オブジェクトを利用可能な最も低い位置に移動します。 "top of gen2"マーカーは、新しくコピーされたgen1オブジェクトのすぐ上に設定されます(現在gen2にあります)。同様に、 "top of gen1"マーカーは、新しくコピーされたgen0オブジェクトの一番上に設定されます。 – supercat

+0

このすべての目標は、gen0より上の連続した空き領域を解放することです。 gen2を圧縮する理由の大きな部分は、gen1オブジェクトを下に移動させることです。同様にgen1を圧縮することで、gen0オブジェクトを下に移動させることができます。オブジェクトが "生きている"かどうかの判断をスピードアップするために、.netが使用する変なトリックがあります。実際には、gen2オブジェクトがgen0オブジェクトへの参照を保持している場合、参照が破棄されるかgen2オブジェクト自体が収集されるまで、gen0オブジェクトは収集できません。 – supercat

0

システムが特定の世代のガベージコレクションを実行するときは、その世代のオブジェクトへの参照を保持する可能性のあるすべての単一オブジェクトを調べる必要があります。多くの場合、古いオブジェクトは他の古いオブジェクトへの参照しか保持しません。システムがGen0コレクションを行っている場合、Gen1および/またはGen2の参照のみを保持するオブジェクトは無視できます。同様に、Gen1コレクションを行っている場合、Gen2への参照のみを保持するオブジェクトは無視できます。オブジェクトの検査とタグ付けはガベージコレクションに必要な時間の大部分を占めるため、古いオブジェクトをスキップできることはかなりの時間を節約します。

ちなみに、オブジェクトが新しいオブジェクトへの参照を保持するかどうかをシステムがどのように知っているのか疑問に思うなら、オブジェクトはオブジェクトが記述されていれば各オブジェクトの記述子に2ビットを設定する特別なコードを持っています。最初のビットは各ガベージコレクションでリセットされ、次のガベージコレクションでまだリセットされている場合、システムは、オブジェクトが最後に書き込まれたときに存在し、以前のコレクションではGen1またはGen2になります)。 2番目のビットは各Gen1ガベージコレクションでリセットされ、次のGen1ガベージコレクションでまだリセットされている場合、システムはGen0オブジェクトまたはGen1オブジェクトへの参照を含むことができないことを認識します(参照を保持するオブジェクトは現在Gen2です) 。システムには、オブジェクトに書き込まれた情報にGen0またはGen1参照が含まれているかどうかはわかりません。タグなしオブジェクトに書き込むときに必要なトラップは高価で、オブジェクトを書き込むたびに処理する必要がある場合はパフォーマンスを大きく低下させます。これを避けるために、オブジェクトにはのいずれかの書き込みが発生するたびにタグ付けされるため、次のガベージコレクションの前に追加の書き込みを中断することなく処理できます。

関連する問題