Bitmap marking GC

Preview:

Citation preview

わだあつし @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