DのGC
class Foo { public string name = "foo"; } void main() { auto foo = new Foo; GC.free(cast(void*)foo); writefln(foo.name); // -> foo writefln(foo); // -> object.Error: Access Violation }
D言語のバージョン2.020からD runtime projectのおかげでコア部分が大きく変わって,GCはcore.memoryのGC構造体からアクセスできるようになったので試してみたのだけど,上のってバグ?
そもそもGCに関してはよく理解してなくて,GCの各クラスメソッドに渡すvoid*ってオブジェクトのポインタでいいよね(ブロックの範囲ってPoolのテーブルでいいのかな?).
GCでのfreeって流し読みした感じだと,サイズによってPoolの値を埋め尽くすのと,フリーリストに繋ぐ二つに分かれてる気がするんだけど,これだと領域のfreeはしてないような(freeの印があるのがGCされた状態ってこと?).やっぱ一からGCのソースを読んで理解するしかないのかなぁ.
というかcast(void*)objで得られるのがオブジェクトのアドレスだとしたら,現状オブジェクトのtoHashで得られる値ってポインタの数値ってことでいいのか?
return cast(hash_t)cast(void*)this;
中身これだし.でも'BUG: this prevents a compacting GC from working, needs to be fixed'って書かれてるから,いずれコンパクションを実装する予定があるんだろうか?あー,分からんことだらけ.
追記
GC.minimizeを行うとfreeされるのかな.恐らくPoolが実際の割り当て領域で,これをfreeしてるのがminimizeしか見当たらない.fullCollectもmark処理をした後,sweep処理の所はフリーの印をつけてリストやページを再構築し直してるだけっぽいし.
というかminimizeが既にPoolのコンパクションをしてると思うのだけど.この辺の処理はもう少し詳しく見てみないと駄目っぽいな.