View
278
Download
0
Category
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
Recommended