Rubyによる本気のGC¶ ↑
: subtitle
Serious GC with Ruby
: author
@nari3
: content-source
#sprk2012
: date
2012/9/15
: institution
ネットワーク応用通信研究所
: allotted-time
25m
: theme
nari
# 目標枚数 : 140枚
Note¶ ↑
準備: information, ペンモード(右クリック+右下)
札幌自体は過去のすべてをリモート参戦していました。感極まりますね。
提供¶ ↑
# image # src = images/nacl_logo.png # relative_width = 90
スライドプロパティ¶ ↑
: size
8
Note¶ ↑
このプレゼンテーションの提供は、オープンソースフロンティア、協調と革新のNaClの提供でお贈りします。
札幌までの交通費を出していただきました。
札幌RubyKaigiで発表するならNaClに入るしかない。
うなぎの件¶ ↑
# image # src = images/nacl_wantedly.png # relative_width = 90
((‘tag:x-small:((<URL:www.wantedly.com/projects/478>))’))
p¶ ↑
: size
2
Note¶ ↑
Wantedlyでうなぎ食べられる感じのやつを出しています。
弊社に興味がある方はぜひ。ひやかしはお断りしております。
自己紹介¶ ↑
-
中村成洋/@nari3/nari/authorNari
-
CRubyのコミッタ
-
((‘wait’))GCメンテナ&デストロイヤ
GCとは(ry¶ ↑
Note¶ ↑
ガーベッジコレクションの略ですね。
((*GoogleTrendでみるGC*))¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/google_trend_00.png
:background-image-relative-width
90
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/google_trend_01.png
:background-image-relative-width
90
Note¶ ↑
Trendの説明: Googleでどれくらい検索されたか✕日付
このグラフからわかることはなんでしょうか?
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/google_trend_03.png
:background-image-relative-width
90
Note¶ ↑
参考のためにRubyのTrendがこちらです。GCがこっち、Rubyがこっち。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/google_trend_02.png
:background-image-relative-width
90
休日の検索数がnさがっている¶ ↑
p¶ ↑
: size
8
:color
white
:background-image
images/google_trend_02_with_gray.png
:background-image-relative-width
90
:background-color
gray
つまり¶ ↑
-
平日
-
お仕事でGCを作るリア充
-
もしくはGCバグに悩まされる一般ピープルが多い
-
-
休日
-
趣味でGCをいじる人が少ない
-
Note¶ ↑
そのてんRubyはすごいよね。休日までたっぷり検索されてて。 愛されているなとすぐわかりますね。
GCはまだまだ愛されていない¶ ↑
ちなみに:年末も異常に検索されている¶ ↑
# image # src = images/google_trend_04.png # relative_width = 90 # caption = リアルGCの恐れ..
とにかくnGCをもっとnよく知りましょう!¶ ↑
((*徹底解剖G1GCn 実装編*))n正式版公開!!n(無料配布)¶ ↑
p¶ ↑
:size
6
:headline-align
left
:background-image
images/gcbook.jpeg
:background-image-align
right
:background-image-relative-margin-right
3
:background-image-relative-height
90
:background-image-relative-width
40
Note¶ ↑
ついこの間までβだったんですが、昨日正式版を公開しました。 無料で公開しておりますので興味がある人はのぞいてみてください。
この場を借りて本書のスポンサーのみなさまありがとうございますnm(_ _)m¶ ↑
((*Ruby2.0 の GC update*))¶ ↑
Note¶ ↑
そういえば、来年はRuby20周年を記念して2.0がでるそうです。
GCには一個だけ大きな修正が入っています。
偉い人がいってた¶ ↑
「全力で潰す」¶ ↑
p¶ ↑
:size
8
:headline-position
bottom-right
:background-image
images/matz.jpg
:background-image-relative-height
100
:background-image-relative-width
100
:color
white
:background-image-credit
http://www.flickr.com/photos/recompile_net/5952564080
Note¶ ↑
mrubyでCRubyを潰そうとしていると推測してます。
昨日、「CRubyはがんばってね」みたいなこといってて腰抜かした。
Matz mashes something, so we mash something.¶ ↑
Note¶ ↑
まつもとさんがなにか潰すならわれわれもなにか潰さねばならぬ
僕もなにか潰したい!¶ ↑
REE is dead¶ ↑
# image # src = images/phusion_passenger_01.png # relative_width = 70
((‘tag:x-small:((<URL:blog.phusion.nl/2012/02/21/ruby-enterprise-edition-1-8-7-2012-02-released-end-of-life-imminent/>))’))
Note¶ ↑
日本だとCookなんちゃらさんが使っていることで有名なREEというのがあった。
ついこのあいだ死んだ。
諸君らが愛したREEは死んだ。nなぜだ!¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image-relative-width
100
:background-image
images/phusion_passenger_02.png
Note¶ ↑
死んだ理由が書かれていて
((‘ ’))¶ ↑
p¶ ↑
:background-image-relative-width
90
:background-image
images/phusion_passenger_03.png
Note¶ ↑
copy-on-write patchが2.0に入るからというのが理由の一つ
((‘ ’))¶ ↑
p¶ ↑
:background-image-relative-height
90
:background-image
images/misawa_beihei.gif
Note¶ ↑
それいれたのnオレオレ
BitmapMarking¶ ↑
-
fork使うようなプログラムで嬉しいはず
-
Passengerなどで恩恵があるらしい
REEつぶしたったn(^o^)¶ ↑
最近の悩み: nKijiはnどうやって潰そうか…¶ ↑
Note¶ ↑
Kijiというtwitterで使われているRuby。GCに手を入れている。
ほっときゃ死ぬかな
((*本題*))¶ ↑
RubyでGCを書くというお話¶ ↑
((*動機(1)*))¶ ↑
((R))ubyKaigi ((D))riven ((D))evelopment¶ ↑
過去のRubyKaigiの発表…¶ ↑
-
LazySweepGC - RubyKaigi2008
-
LonglifeGC - 2009
-
LazySweepGC - 2010
-
ParallelMarkingGC - 2011
全部Cの話やないか!¶ ↑
((‘ ’))¶ ↑
# image # src = images/slam_01.jpg # relative_width = 70 # caption = Rubyの話、させてください
Note¶ ↑
誰も止めてはいないんですが。
((*動機(2)*))¶ ↑
((‘ ’))¶ ↑
# image # src = images/c_must_die_00.png # relative_width = 80
Note¶ ↑
卜部さんの記事。大変感銘を受けた。
((‘ ’))¶ ↑
# blockquote # title = 卜部昌平のあまりreblogしないtumblr 結論:C死ね。
ほんとどのGCはnC or C++で書かれているしなぁ…¶ ↑
((‘ ’))¶ ↑
# blockquote # title = 卜部昌平のあまりreblogしないtumblr なぜCで書く必要がある?ないはずだよ。ちゃんと調査すればJavaとかC#とか、ひょっとしたらOCamlやScalaででも用は足りる場合がほとんどなんだ。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/misawa_tamesita.gif
:background-image-relative-height
80
Note¶ ↑
かってに試されているような気分になった
RubyでGCn書いてみよう!¶ ↑
Note¶ ↑
単純な興味、RubyでGCはかけるのか?
素直に考えると…¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/cruby_on_gc.png
:background-image-relative-width
100
Note¶ ↑
よくArrayをヒープと見立ててGCをエミュレートしているのを見かける。
アルゴリズムの勉強をするために書かれたりする。
当たり前だがRubyで書かれたものはCRubyからオブジェクト確保、そのオブジェクトはCRubyで管理しているものである。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/misawa_akita.gif
:background-image-relative-height
80
Note¶ ↑
2年前くらいにやったことがある。
これはあまり意味がない¶ ↑
-
下にいるGCの性能に影響をうける
-
性能評価しづらい
-
下のGCが遅いと、上のGCも遅くなる
-
これはあまり意味がない¶ ↑
-
言語処理系にGCは1つあればいいですよ感
-
無駄に話が複雑になっているような気がする
-
もっと違うアプローチを考えよう!¶ ↑
Note¶ ↑
というのが、今回のプレゼンの本題です。
((*Meta-circular evaluator*))¶ ↑
((‘ ’))¶ ↑
# blockquote # title = 4.1 The Metacircular Evaluator - SICP An evaluator that is written in the same language that it evaluates is said to be ((*metacircular*)).
Note¶ ↑
同じ言語で書かれた評価器で評価することメタサーキュラーと呼ぶのです。
簡単な例:nLISPでLISP書いたった¶ ↑
他の具体例を調べてみる¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/pypy.png
:background-image-relative-width
70
Note¶ ↑
pypyというのはみなさんご存知でしょうか? ノシ なぜかニヤニヤしている人もいるようですが…。
蛇が蛇自身を食べるこの図ですべて表されていますが、pypyというはPythonで書かれたPython処理系です。
もう少し詳しく¶ ↑
-
RPython(Restricted Python)で実装
-
Pythonの言語サブセット
-
-
RPython -> C/LLVM/Java..
変換イメージ¶ ↑
Note¶ ↑
RPythonがどのようにして実行できる形式に変換されるか?
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/pypy_translate_00.png
:background-image-relative-width
100
Note¶ ↑
まず、RPythonで書かれたPython処理系のpypyがある。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/pypy_translate_01.png
:background-image-relative-width
100
Note¶ ↑
これをCPythonでバックエンドのソースコードに変換します。 このバックエンドはJavaとかCとか選べるんですが、説明ではCとしておきます。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/pypy_translate_02.png
:background-image-relative-width
100
Note¶ ↑
最終的にオブジェクトファイルに変換される。 実行できるPython処理系のできあがり。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/pypy_translate_04.png
:background-image-relative-width
100
((*重要なポイント*))¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/pypy_translate_03.png
:background-image-relative-width
100
GCもRPythonで書かれている¶ ↑
p¶ ↑
:color
white
:background-image
images/pypy_translate_03_with_gray.png
:background-image-relative-width
100
((*疑問*))¶ ↑
Note¶ ↑
この説明を見た時に一つだけ疑問があった。
GC動作中のGCはどうするのか?¶ ↑
-
GC動作中にGCが起きて、その動作中にGCが起きて…
-
GCの無限ループ…?
-
Note¶ ↑
RPythonのGCもRPythonで書かれているわけですよ。
RPython¶ ↑
-
GC中はGC対象のオブジェクトを作らないように気を付ける(たぶん)
-
mallocなどで直接メモリを切り出す
-
libffiを利用
-
-
GC中にGCが走ることはない¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/rubinius.png
:background-image-relative-width
70
Note¶ ↑
次のメタサーキュラー評価器はみなさんご存知のRubiniusです。 RubyをなるべくRubyで実装している。
仕組み(ry¶ ↑
ただし¶ ↑
-
GCをRubyで書く仕組みがない
-
今考えればRubiniusをいじったほうがよかったかも…?
-
まぁいいか…
-
-
# 55枚
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/jikesrvm.png
:background-image-relative-width
70
Note¶ ↑
こちらはJavaでJavaVMを書いたもの。 こちらはRPythonみたいなサブセットではなくJava言語がフルで使える。
JikesRVM¶ ↑
-
((‘tag:x-small:RVM(Research Virtual Machine) = 研究用VM’))
-
GC,VM周りでたくさん論文が書かれている
-
JikesRVM¶ ↑
-
GCもJavaで書かれている
-
プロジェクト委員の一人がRechard Jones(RJGC著者)
直接オブジェクトファイルを吐く¶ ↑
# image # src = images/jikesrvm_01.png # relative_height = 90
Note¶ ↑
pypyとは違って直接オブジェクトファイルを吐く
ほんとうはもう少し難しい図になる。 詳細をはぶくとだいたいこんなかんじ。
GCもJavaで書ける¶ ↑
-
一緒にオブジェクトファイルに変換される
-
GC中はGCが発生しない
-
PyPyと同じ理由
-
JikesRVMの功績はn「GCをJavaでかける」nだけではない¶ ↑
Note¶ ↑
実は…
GC部分が((MMTk))という((*別部品*))に切り離されている¶ ↑
MMTk(Memory Management Tool kit)¶ ↑
-
GCを11個保有
-
ツールキットなのでGC用の便利メソッドが沢山ある
-
GCづくりが簡単
-
MMTk(Memory Management Tool kit)¶ ↑
-
VMからメモリ管理を別の部品として切り離せる
-
VMは取り替え可能
-
JikesRVM
-
Harness
-
-
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/mmtk_00.png
:background-image-relative-width
100
Note¶ ↑
VMとMMTkは完全に別の部品になっている。
MMTkが定義するインターフェイスを守ってVMを実装すればいい。 その例がJikesRVM。
MMTkがOSにメモリを要求したり、開放したりする。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/mmtk_01.png
:background-image-relative-width
100
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/mmtk_02.png
:background-image-relative-width
100
Note¶ ↑
起動時にどのGCを使うかを選択することができる。
やたー!nGC書き放題!¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/mmtk_03.png
:background-image-relative-width
100
Note¶ ↑
このマークをよく観るとわかるんですが、そうなんですよねみなさんの嫌いなJavaでGC書かないと行けないんですよ。
Javaで…¶ ↑
Note¶ ↑
あぁ、Javaで書くのか…
Rubyで書きたい…ッ!!¶ ↑
((‘ ’))¶ ↑
Note¶ ↑
こんな感じでRubyで書けない?
p¶ ↑
:background-image
images/mmtk_04.png
:background-image-relative-width
100
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/mmtk_05.png
:background-image-relative-width
100
Note¶ ↑
ついでにVM側のRubyで書けない?
われわれにはJRubyがあるじゃないか¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/regicide_mmtk_00.png
:background-image-relative-width
100
Note¶ ↑
JavaにJRubyを埋め込んで、ユーザが定義したRubyコードを埋め込んだJRubyコードに評価させる、ということを考えました。
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/regicide_mmtk_01.png
:background-image-relative-width
100
この部分をnライブラリ化¶ ↑
((R))e((g))i((c))ide¶ ↑
Regicde = 国王殺し¶ ↑
# image # src = images/regicide.png # relative_width = 80
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/regicide_mmtk_02.png
:background-image-relative-width
100
Note¶ ↑
Regicideを使えばユーザはVMをJRubyで書いたり、GCをJRubyで書くだけで済んじゃう。 難しいところはRegicideが吸収。
サンプルコード¶ ↑
オブジェクトの定義¶ ↑
# enscript ruby class FixnumValue < Regicide::Mutator::ObjectValue # ... end
((‘tag:x-small:Regicide::Mutator::ObjectValueを継承’))
オブジェクト生成¶ ↑
# enscript ruby class FixnumValue < Regicide::Mutator::ObjectValue # Fixnumをフィールドに持つ # オブジェクトを割り当てるメソッド def self.from_i(mutator, i) ... end end
from_i¶ ↑
# enscript ruby # メモリ割り当て ptr = mutator.alloc(0, 1, mutator.current_stack.pc) # オブジェクト生成 v = self.new(ptr) # Fixnumを格納 mutator.store_data_field(v.object_value, 0, org.vmmagic.unboxed.Word.from_long(i)) return v
M&S GCは4行で書ける¶ ↑
# enscript ruby class MSConstraints < org.mmtk.plan.marksweep.MSConstraints; end class MS < org.mmtk.plan.marksweep.MS; end class MSCollector < org.mmtk.plan.marksweep.MSCollector; end class MSMutator < org.mmtk.plan.marksweep.MSMutator; end
動作するサンプルn↓n((‘tag:x-small:((<URL:github.com/authorNari/regicide/tree/master/sample>))’))¶ ↑
((*苦労話*))¶ ↑
Java+JRuby¶ ↑
-
JRuby側からJavaを使うのは簡単
-
メソッド呼び出し
-
継承とかとか
-
Java+JRuby¶ ↑
-
Java側からJRubyを使うのは難しい
-
けっこう意外だった
-
どいうことか?¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/jruby_plus_java_00.png
:background-image-relative-width
100
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/jruby_plus_java_01.png
:background-image-relative-width
100
どうやるのn(?_?)¶ ↑
RedBridge¶ ↑
p¶ ↑
:color
white
:background-image
images/rubybridge.png
:background-image-relative-width
100
:background-image-relative-height
100
RedBridge¶ ↑
-
@yokoletさん作(感謝!)
-
Javaの中でJRubyの実行環境(コンテナ)を作る
-
コンテナにソースコードぶちこんだり、Rubyコード片を評価できる
-
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/jruby_plus_java_01.png
:background-image-relative-width
100
Note¶ ↑
この図の例だと
イメージ¶ ↑
# enscript java public static void foo(void) { // JRuby実行環境作って ScriptingContainer sc = new ScriptingContainer(); // さっきのJRubyFooクラスを読み込み Object jrubyFooClass = sc.runScriptlet(PathType.ABSOLUTE, "foo.rb"); // JRubyFoo.fooを呼び出す sc.callMethod(fooClass, "foo", Object.class); }
Regicideではnこの辺の技術をnなんやかんやn使ってます¶ ↑
((*Regicideの悪いところ*))¶ ↑
((*VM作るのめんどい*))¶ ↑
けっきょくVMは書かないといけない¶ ↑
-
GCを評価するためにはある程度ちゃんとしたものが必要
-
でもVMとか興味ないしさぁ…
-
-
LISPすら作るのが億劫
-
飽きてきた
((*JVMのGCのn影響を受ける*))¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/regicide_bad_00.png
:background-image-relative-width
90
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/regicide_bad_01.png
:background-image-relative-width
90
Note¶ ↑
こういう変換ができると思っていた。
((‘ ’))¶ ↑
# image # src = images/regicide_bad_02.png # relative_width = 80 # caption = ふつうにJavaのコードとして動かす感じ
JVMのGCに引っ張られる¶ ↑
-
性能が引っ張られる
-
GC停止も不可能だしきちんと性能評価しづらそう
-
論文とか書きづらそう
-
-
変換ができればいいのに…¶ ↑
-
JikesRVMのブートストラップ部分にJRubyを突っ込む
-
うまく動かなかった
-
JRubyがJikesRVMの秘孔を付いているらしい
-
JikesRVMがまだ未熟
-
-
((*Regicideの良いところ*))¶ ↑
((*VMが自分で書ける*))¶ ↑
言語処理系が自前で書ける¶ ↑
-
GCにすごく優しい処理系とか書ける
-
言語処理系ひっくるめて検討できる
おいしいところは全部Rubyで書ける¶ ↑
-
VM, GC, 全部Rubyで書ける
-
Cみたいに阿鼻叫喚しなくていい(かもしれない)
-
生産性が100倍(らしい)
勝手に処理系が速くなる感¶ ↑
-
JVM速くなる = Regicide速くなる
-
WIN-WIN(笑)
-
Cでも一緒か…
-
-
ほかのGCと比較可能¶ ↑
-
十数個のGCと性能比較ができる
-
起動時のオプションを少しいじるだけでOK
-
論文とかかけるかもしれない!
-
githubにあげていますnauthorNari/regicide¶ ↑
((*今後の展開*))¶ ↑
作ってみて気づいたこと¶ ↑
-
GC部分は外っ面がRubyなだけで実はCとあまり変わらない感じ…
-
これならCで書いても一緒なのでは…
-
作ってみて気づいたこと¶ ↑
-
実はGC実装に特化したミニ言語が欲しいだけなのか…?
-
今後はそちら方面で攻めてみたい
-
((*まとめ*))¶ ↑
まとめ¶ ↑
-
やっぱりRubyの話できなかった
-
C死ねと思って作ったRegicideがすでに死にそう
Note¶ ↑
Python,Java,JRubyの話とかしてしまった
ご清聴nありがとうnございました¶ ↑
((‘ ’))¶ ↑
p¶ ↑
:background-image
images/misawa_riakai.gif
:background-image-relative-height
80