java.lang.ref.Reference

http://d.hatena.ne.jp/taedium/20041215のコメントでid:nminoruさんからまたまたおもしろいことを教えてもらいました。参照オブジェクトはいったんReferenceクラスで一元管理されてからReferenceQueueに入れられるのですね。

どんな風に動くのか、finalizeメソッドを持ったクラスのインスタンスhogeをWeakReferenceとReferenceQueueで管理する場合をイメージしてみました。

Hoge hoge = new Hoge();                         (1)
ReferenceQueue q = ReferenceQueue();            (2)
WeakReference wr = new WeakReference(hoge, q);  (3)
hoge = null;                                    (4)
System.gc();                                    (5)
// このSystem.gc()でgarbage collectionが行われ、
// かつgarbage collectorがhogeをweakly reachableと判断すると仮定する

上のようなコードがあるとして

  • まずbootstrap classloaderによるクラスのロードが行われる。
    • ReferentクラスがロードされるときReferenceHandlerが動き、Referenceクラスのstaticなpending変数がnullでなくなるまでwait。
    • FinalizerクラスがロードされたときFinalizerThreadが動き、FinalizerクラスのstaticなReferenceQueueに値が入るまで待つ。
  • (1)のときJavaVMがFinalizerのインスタンスを生成する。
  • (2)と(3)でhogeのweakly referenceとqueueを関係付ける。
  • (4)でhogeがstrongly reachableでなくなる。
  • (5)でgabage collectionがはじまる。
    • garbage collectorはhogeをfinalizableと宣言する。このときgarbage collectorは(1)で作成されたFinalizerのインスタンスをReferenceクラスのstaticなpending変数にキューイングする。
    • garbage collectorはhogeをweakly reachableと判断する。このときgarbage collectorは(3)でインスタンス化されているWeakReferenceをReferenceクラスのstaticなpending変数にキューイングする。さらにここでWeakReferenceのreferentがclearされる?
  • garbage collectionが終わる。
  • JavaVMによりReferenceHandlerが起こされる。
    • pending変数にキューイングされていたFinalizerがReferenceQueueにenqueueされ、FinalizerThreadが動き出す。
    • pending変数にキューイングされていたWeakReferenceがReferenceQueueにenqueueされる。

<疑問>

  • WeakReferenceがReferenceQueueにenqueueされたときには必ずしもreferentのfinalize()が実行されているとは限らないみたいです。JavaDocにはfinalizableになるとはあってもfinalize()が実行されるとは書いてないですね。http://www-128.ibm.com/developerworks/java/library/j-refs/index.htmlの「Garbage collector and reference interaction」の節を見るとfinalize()が実行されてからenqueueされるように読めましたが、「After」じゃなくて「When」とあるところがミソなのでしょうか。(ミソって最近言わないかも...)
  • WeakReferenceのreferentのclearはどこで行われるかわかりませんでした。アプリケーションがWeakReference#get()を呼び出したときにnullが返るけどまだReferenceQueueにenqueueされていないということが起きてもいいんでしょうか。
  • これは疑問ではないですが、到達可能性と参照の強さの概念ってときどきごっちゃになります。