Javaの参照とDの参照
OpenJDKで提供されているJDK 6のソースを眺めていた.java.lang.refパッケージにそれぞれのクラスがあって,これが実装のはず.
- SoftReference
- WeakReference
- PhantomReference
- Finalizer
これらが重要だと思うんだけど,強参照は組み込みなのでないのかな(Referenceは抽象クラスだし)?で,どうやって使い分けてるのかと見てみると,WeakReferenceの場合だと
public WeakReference(T referent) { super(referent); } public WeakReference(T referent, ReferenceQueue<? super T> q) { super(referent, q); }
コンストラクタがこんな感じで,他の*Referenceもこんな感じ(Softはタイムスタンプ持ってるけど).スーパークラスのReferenceはこのreferentを自身のreferentに代入しているだけで,これだと強参照.気になってるのは,JavaのGCがそれぞれの参照をどう判断してるのかの部分.上の初期化だと内部は強参照だし,GCが回収する時に特別な処理をしているんだろうか?この辺はJava言語仕様でも読めば出てくるのかな.
ファイナライザって解放時の処理のやつだと思うんだけど,どこで関連付けてるんだろう?というかReferenceQueueに到達可能性が変更されて登録されたら,また参照が増えるような,うーん(´-`)
もしJavaがrefパッケージのクラスを特別扱いしているのなら,現状のD言語のGCだと勿論無理だし,昨日書いたRubyのWeakRefみたいにオブジェクトのidを取得してObjectSpace経由みたいなアクセスも無理.
何とかGC経由でしたいのだけど,void*でのアクセスはブロック単位が基本みたいだし(queryの返り値はBlkInfo),アドレスをほげほげして出来るのかなぁ?addrOfとか?取得できるならopDotとかで委譲出来そうなんだけど,もう少しGCの理解が必要か.色々足りないものがありすぎるorz
というかなんでstruct GCなのに,その実装の方はstruct Gcxなんだろう.GCxの方がいい気がするんだけど…
追記
http://www.ibm.com/developerworks/jp/java/library/j-jtp01246/
ここのページの途中に書いてあったけど,JavaだとやっぱりReference系は特別扱いしてるみたいだ.このアプローチをするなら,処理系を弄るしかないので無理か.