わだあつし @wats
Ruby 2.0 の
Bitmap Marking GC
って美味しいの?
Tuesday, December 4, 2012
自己紹介
• わだあつし @wats
• 株式会社 寿限無やってます
• fukuoka.rb とか coder dojo とか fukuoka.py
とか明星和楽とか
• 来年からスクールをはじめます!
Tuesday, December 4, 2012
• Garbage Collection ( =ゴミ 収集)
• メモリの自動開放機構
GCのおさらい
Tuesday, December 4, 2012
• 不要になったオブジェクト = メモリ領域
• どうやって判定するのか?
ゴミとは?
Tuesday, December 4, 2012
• シンプルなMark & Sweep 方式
• 必要なオブジェクトをマークして、マークされなかっ
たものをゴミ認定
• JavaのGenerational GCのような生存期間に合わせた再
配置などもない。
• そもそもコンパクションの機構もないみたい!
今までの Ruby GC
Tuesday, December 4, 2012
• Ruby1.9まではマークされたことを示すフラグは各オブジェク
ト構造体の中にある。
• GCを行うと生存するオブジェクトに変更が入るということ
• マークする = write している。
マーク
( = オブジェクトへの変更)
Tuesday, December 4, 2012
• fork()というシステムコールを内部で使っ
ているのがほとんどらしい
• fork() : 子プロセスを作る
唐突にRack アプリケーション
の一般的な構造
Tuesday, December 4, 2012
• 生成当初は親プロセスのメモリをそのまま参照する。
子プロセス生成の動き1
(OSによるかも。)
Tuesday, December 4, 2012
• 子プロセスからそこへの書き込み = write が発生して初め
てプロセス毎の差異がでる。
子プロセス生成の動き
(OSによるかも。)
Tuesday, December 4, 2012
• その時その部分のメモリ領域を子プロセスが複製 =
copyし、そこに書き込む = write する。
• これがいわゆる copy on write
• だから、親プロセスからはメモリは元の状態のまま
子プロセス生成の動き
(OSによるかも。)
Tuesday, December 4, 2012
write があるとcopy
Tuesday, December 4, 2012
GCが走ると生存しているオ
ブジェクトにマークのため
writeされる。
Tuesday, December 4, 2012
オブジェクトに実質的に差異が発生し
ていないのにプロセスごとに全てコ
ピーされる
Tuesday, December 4, 2012
これがサーバサイドRubyのメ
モリ消費を増大させている。
Tuesday, December 4, 2012
• writeされているのは、生存していること
を示すマーク用の1bitだけ
• なら、オブジェクトはそのままプロセス
間で共有させておきたい。
• マーク用1bitだけを別領域にだしちゃお
う
これを何とかしたい!
Tuesday, December 4, 2012
• GCのマーク用1bitだけを、オブジェクト
から別領域に抜き出し
• GC時のwriteがその別領域だけになるの
で、オブジェクトは共有のまま
• 最低限のオブジェクトのコピーだけが発
生するようになる。
それが Bitmap Marking GC
Tuesday, December 4, 2012
• Unicorn や Passenger使っているところで
はメモリ消費が下がるはず。
• GCの際のマークに1step増えるので、GC
の時間は微増らしい
• 子プロセス作らんようなところ(ただの
rubyスクリプトとか)には恩恵ないかと
まとめ
Tuesday, December 4, 2012
• なんでOSのスレッド使わんのですっけ?
そもそも
Tuesday, December 4, 2012
• 今日のパクリ元
• http://patshaughnessy.net/2012/3/23/why-you-should-be-excited-about-
garbage-collection-in-ruby-2-0
• http://www.narihiro.info/resource/presen/bitmap_gc.pdf
• Rubyのスタックフレーム
• http://i.loveruby.net/ja/hack/frame.html
• Ruby Enterprise Edition はそもそもそんなGCらしい
• http://www.rubyenterpriseedition.com/download.html
参考
Tuesday, December 4, 2012
大分おおざっぱなメ
モリモデルのおさらい
Tuesday, December 4, 2012
スタック領域とヒープ領域に
論理的に分けて使う
Tuesday, December 4, 2012
メソッドコール毎にスタック
にスタックフレームが積まれ
る
Tuesday, December 4, 2012
Rubyの場合、全てオブジェク
トなのでヒーブに作られる。
Tuesday, December 4, 2012
• ※実際は、ローカル変数を束縛したProcを返したりす
るので、もっと複雑。あくまで概要
メソッドが終了すると、そのスタックフレームがpopされ、
前のメソッド(スタックフレーム)の途中から再開
Tuesday, December 4, 2012
Mark & Sweepのおさらい
Tuesday, December 4, 2012
ヒープにはどんどんオブジェクトがで
きるのでいつか足りなくなる。
Tuesday, December 4, 2012
もう使わなくなったオブジェ
クトもあるはず。。。
Tuesday, December 4, 2012
• 参照は、直接も間接も含む
使わなくなったオブジェクト = メソッド(スタックフレー
ム)からの参照がない
Tuesday, December 4, 2012
• こいつが「write」してる
スタックから参照があるオブジェクトを再帰的にたどって
マークする。
Tuesday, December 4, 2012
• = 要らない子
• = GC対象
マークされなかったものは参
照されていない。
Tuesday, December 4, 2012
そのアドレスを要らない子リストに追加して、今後そこか
らメモリを供給していく
Tuesday, December 4, 2012

Bitmap marking GC