BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース CLR 4でガベージコレクタが改善される

CLR 4でガベージコレクタが改善される

ブックマーク

原文(投稿日:2009/6/4)へのリンク

CLR GCの開発オーナーであるMaoni StephensとCLR GCのPMであるAndrew Pardoeは、Channel 9インタビューの中でCLR 4にバックグラウンドGCを導入したことを説明している。この基本的な仕組みは最初のGCが動作している最中にもう一つのGCを開始することができるというものであり、ガベージコレクションプロセスの効率が改善される。

以前から2種類のGCが存在していた。ワークステーションとサーバーである。ワークステーションGCはコンカレント実行をオンまたはオフにして動作させることができた。

ワークステーション/コンカレント実行なし ―― メモリ割り当てに責任を持つマネージスレッドにおいて利用できるメモリ空間が不足すると、同じスレッドで動作するGCが呼び出される。GCは他の全てのマネージスレッドを停止し、メモリを片づけて、停止したマネージスレッドの動作を再開し、元のスレッドに制御を返す。

ワークステーション/コンカレント実行ありコンカレントGCとも呼ばれる) ―― 上のシナリオに似ているが、GCが使われていないメモリを回収する間、マネージスレッドをずっと停止しておくわけではない。マネージスレッドは自身の作業を続けることができ、メモリを割り当てることも可能だが、下に記述するような若干の制限がある。gen0オブジェクトのためのメモリプールは、割り当てのニーズを満たすために、前のシナリオの場合よりも大幅に大きい。利用可能なメモリがなくなれば、スレッドはやはり停止させられる。

MaoniはコンカレントGCをこのように説明している

(コンカレント GC では)コンカレント GC が動作中でもメモリを割り当てることができます。しかし、それほど多くは割り当てられません ―― 小さなオブジェクトについては、最大でもエフェメラルセグメントの終端までしか割り当てることができません。エフェメラル GC を実行しない場合、短命な世代によって使用可能な総メモリ空間は、セグメント全体で使用可能な大きさと同じであることに注意してください。したがってセグメントの終わりまで行くと、コンカレント GC が完了するまで待たなければならないので、小さなオブジェクトの割り当てを必要とするマネージスレッドは停止されます。

コンカレント GC の実行中は、GC のいくつかのフェーズを実施するために、マネージスレッドを 2 回停止する必要があります。これらのフェーズは完了するまでに時間がかかる可能性があります。

サーバー ―― こちらの場合は、CPUごとに、専用のスレッドとメモリヒープで動作するGCが存在する。メモリを割り当てるスレッドにおいて利用できるメモリ空間が不足すると、そのスレッドはGCスレッドに通知する。GCは各CPUで動作しているマネージスレッドをすべて停止し、メモリを片づけ、作業を終えたことを通知し、停止したスレッドを再開する。

コンカレント動作なしのワークステーションGCとサーバーGCは、GCの動作中に実行が継続しているような活動がないため、ブロッキングGCと呼ばれている。

GCの種類は、ランタイム構成ファイルに<gcConcurrent></gcConcurrent><gcServer></gcServer>を設定することで選択できる。そして、GCの介入は、実行時にLatencyModeプロパティをGCLatencyMode値の中の1つ(Batch、Interactive、LowLatency)にセットすることで設定できる。

.NET 4.0ではバックグラウンドGCが導入される。コンカレントGCは動作中にメモリを割り当てるが、その時点でのセグメントの範囲内だけであり、その大きさはワークステーションGCでは16MBしかない。それが尽きた後はすべてのスレッドが停止する。バックグラウンドGCでは、完全なGC ―― gen0、1、2 ―― が動作している最中に別のエフェメラルGC ―― gen0とgen1 ―― を開始できる。すなわち、別のメモリセグメントにもアクセスできる。Maoniは次のように説明している。

バックグラウンド GC はコンカレント GC が進化したものです。バックグランド GC の重要な点は、バックグラウンド GC の実行中であっても、必要な場合にはエフェメラル GC を実行可能であることです。コンカレント GC と同様に、バックグラウンド GC はフル GC にのみ適用可能ですし、エフェメラル GC は常にブロッキング GC として実行され、かつバックグラウンド GC も専用の GC スレッドで実行されます。バックグラウンド GC の実行中に行われるエフェメラル GC のことをフォアグラウンド GC と言います。

CLR 4.0では、バックグラウンドGCはサーバーで利用できない。しかし、将来のバージョンでの導入は検討中である。なお、ドキュメントには以下のような忠告が記載されている。

2GB 以上のメモリを搭載したサーバーでは、システムでまだメモリが利用できるにもかかわらず、メモリ不足の問題が発生することを防ぐために、 boot.ini ファイルに /3GB スイッチを指定する必要があるかもしれません。

また、.NET 3.5で提供される通知メカニズムを利用することもできる。GCは、回収の直前と直後に通知するように設定できる。これにより、異なるサーバー間で作業のバランスをとり、GCによる中断を防ぐことができる。

この記事に星をつける

おすすめ度
スタイル

BT