著作一覧 |
・2.1のGC
マークビットをビットマップへ移動したので、予約ビットと合わせて2ビット空いた。
そのうち1つを世代別GC用に利用する。
マーク時に世代ビットも立てる。
新世代用GC時に、上記ビットが立っているオブジェクトを発見したら、そのオブジェクトから先はマークしない。
マークフェーズが速くなった。
a.b = c の状態でGCしてaが旧世代となった後に、a.b = dした場合に、cが実際には不要化されたのに残る。それはフルGC時にスィープできるから良いとしてdはマークされないんじゃないか? どうやってるんだろう。(追記:下で書いているSHADYと不可分な話だった。SHADYかつリメンバオブジェクトであれば旧世代(PROMOTED)とはしないといった制御をしている)
もう1つのビットを日陰者と日陽者とする。陽なオブジェクトとするかどうかは、Cのコードでライトバリアを陽に設定するかどうかで決まる。既存の拡張ライブラリのものはすべて日陰者となる。
(このへん、ちゃんと理解してないので、なぜそうなったかわからないのだが、世代別と合わせることで、不要オブジェクトの早期回収が可能となるからフルGCの頻度が減るという理解で良いのかな?)
Rubyコアの利用箇所でライトバリアを設定するように改造し、RDocで試したら220秒かかっていた処理が、190秒で終わるようになった。15%の速度向上だ。
というわけで、インフォメーション買った。
インフォメーション―情報技術の人類史(ジェイムズ グリック)
(kindle化されたら買おうとか考えていたが、そういうことを考えた場合の常ですっかり存在を忘れていたし、そこにジュンク堂が来ているのだから今買うしかないなぁと思ったのだった)
長田さんから、おれのC#の本は持ってきたら売れると思うか? と聞かれたので、客層とまったくマッチしないから無理でしょうと最初答えた。しかし良く良く考えてみれば、著者としては不誠実かも知れないと思いなおした。なので、もしかしたら奇特な人もいるかも知れないから、2冊くらいは置いてくれたらうれしいと頼んでみた。
後、Kaigi関連本として、まつもとさんがRubyでは採用しなかったBoehmGCを採用している処理系として名前を挙げられたGaucheの本もポップにそう書いて少し置いてみたらどうかとか。
その伝でいくと、同じく言及があったトランザクションメモリを実装しているClojureについては丁度第2版が出たところなので置いてあったけど、ポップに書けば良いのにと今になって思い出した。
ジェズイットを見習え |
Rubyの実装は読んでませんが、世代別GCの場合、tenureされたオブジェクトが変更される時は、それをwrite barrier等で検出してマークしなおすのが普通だと思います。
普通はwrite barrierはmprotectとか使ってold領域まとめてかけるものなんですが、Rubyはcopy GCじゃないのでoldとnewが混在していてそれができない。したがって書き込みコードで明示的にチェックをしないといけない。だけどそれは開発コストがかかるので、最初から全部対応しなくていい工夫をしました。というのが今回の話です。
最初から対応→陽、そうじゃない→陰ということですね?
ふむ。コード読んでみます。
trunkのソースです。