Ruby 1.9.3は、Narihiro Nakamura氏 (InfoQがポートした)によって書かれた、GCで最も時間がかかるケースで時間を短縮する、遅延解放ガベージコレクター(Lazy Sweep Garbage Collector)を提供する。最新の提案で、Narihiro氏はRuby Enterprise Editionのcopy-on-writeと親和性の高いGCに似た、copy-on-writeと親和性の高いBitmapマーキングGC (または短縮してbmap)を実装した。POSIXのforkシステムコールのように、子プロセスでメモリが変更されたときだけ、親プロセスのメモリをコピーして共有することにより、メモリを削減している。 残念ながら、現在のRubyのGCでは、これはうまく動作しない:
Rubyは、マーク&スイープガベージコレクションを使っている。最初に、すべてのオブジェクトを使用中としてマークします。これは、前述のフィールドにFL_MARKフラグをセットすることです。その後、すべてのオブジェクトをもう一度確認して、マークされていないすべてのオブジェクトを解放します。この問題は、copy-on-writeセマンティクスによるって解決する:効果的にほぼすべてのページが利用されているとマークされます
InfoQは、Narihiro氏に彼のbmap実装は、現在の遅延解放GCよりも改善されているのかを質問した:
Bitmapアルゴリズムの利点は以下の通り:CRubyでは、CoWとの親和性が最も重要です。Bitmapマーキングは、Linuxのfork()を使用しているプログラムのメモリ使用量の問題を改善しています。。私たちは、CRubyで本当のパラレルパフォーマンスが必要な時にfork()を使っています。 そして、私たちはすでにfork()を使った多くのライブラリ(たとえば、Unicorn、Resque)を持っています。
- Bitmapストアは、オブジェクトのヘッダーにマーク用のビットを持っているよりも深くマークされる
- 局所性高い
- マークは、どんなオブジェクトも変更しない。また、解放はどんな生存中のオブジェクトも変更しない。
- 少量のダーティーキャッシュラインで、CoWとの親和性が高い。
- マークビットのクリアにmemset()を使っている
- 解放は、少し早い
InfoQ: 遅延解放GCはスループットを悪化させ、bmapもまた、それよりも遅くなります。bmapは、現行のGCを置き換えますか?それともユーザーや開発者が実行するときに構成できるようにしますか?
私の計画では、BitmapマーキングGCはデフォルトのGCにしたいと考えています。"bmapもそれより少し遅い"と言いましたね。あなたの理解は正しいですが、すべての人に取って許容範囲だと考えています。なので、ユーザーはBitmapマーキングに関する構成が必要ないと考えています。
InfoQ: あなたはまたBitmapマーキングに並列マーキングGCを実装仕様としていると言っていました。これは、GCを大幅にスピードアップするように聞こえますが、大幅に高速化する(または、停止時間を削減できる)アイディアを持っていますか?
実際に、Bitmapマーキングなしでの並列マーキングGCは作成しました。いくつかのケースで、2コアCPUマシン上のGC時間を約40%改善することができました。 Bitmapマーキングの並列マーキングGCは、すべてのGC時間の改善はわずかに落ちるでしょう。
私は、RubyConf US 2011 (ビデオとスライド)で、並列マーキングGCの詳細について話しました。
Matzは、BitmapマーキングGCパッチをRuby trunkにコミットしたため、次のリリース(おそらく2.0)の一部になる予定である。