GC は、クリアされた参照がトポロジ順に ReferenceQueue にエンキューされることを保証しますか?

StackOverflow https://stackoverflow.com/questions/2497014

質問

2 つのオブジェクトがあるとします。 A そして B, 、ポインタがあります A.x --> B, そして、たとえば、次のように作成します。 WeakReference両方に A そして B, 、関連する ReferenceQueue.

両方とも仮定します A そして B 連絡が取れなくなる。直感的に B 以前は到達不可能とみなされません A は。このような場合、それぞれの参照が直感的な (サイクルがない場合はトポロジカルな) 順序でキューに入れられることを何らかの形で保証できるでしょうか。 ReferenceQueue?つまり、ref(B) の前に ref(A) を置きます。わかりません。GC が多数のオブジェクトを到達不能としてマークし、それらを特定の順序でキューに入れたらどうなるでしょうか?

レビューしていました ファイナライザー.java グアバのこのスニペットを見てみましょう:

private void cleanUp(Reference<?> reference) throws ShutDown {
  ...
  if (reference == frqReference) {
    /*
     * The client no longer has a reference to the
     * FinalizableReferenceQueue. We can stop.
     */
    throw new ShutDown();
  }

frqReference 使用される PhantomReference です。 ReferenceQueue, したがって、これが GC されると、Finalizable{Weak, Soft, Phantom} 参照はキューを参照するため、アクティブになることはできません。したがって、キュー自体を GC 処理する前に、これらの参照を GC 処理する必要がありますが、それでも、これらの参照がキューに入れられるという保証は得られるでしょうか。 ReferenceQueue 「ガベージコレクション」を取得する順序で(1つずつGCされるかのように)?このコードは、何らかの保証があることを暗示しており、そうでない場合、理論的には未処理の参照がキューに残る可能性があります。

ありがとう

役に立ちましたか?

解決

発注保証はありません。Finalizer.java の場合、すべての参照が処理される前にスレッドをシャットダウンできます。FinalizableReferenceQueue のドキュメントを参照してください。

  • 関連するすべてのオブジェクトが削除されるまで、このオブジェクトへの強い参照を保持します。

  • 参照対象が確定しました。このオブジェクトが以前にガベージ コレクションされた場合、
  • バッキング スレッドは、
  • 残りの参考資料。

これは意図的な動作です。たとえば、キーや値への参照がクリアされるときに、FRQ を使用してマップ エントリをクリーンアップします。ユーザーがマップへの参照を持たなくなり、さらに FRQ への参照も持たなくなった場合、それらの参照を処理する意味がありません。

他のヒント

私はかなり確信して答えはノーであると思います。

JVMの仕様では、ファイナライザ・メソッドについては、これを言ってます:

  

は、Java仮想マシンがfinalizeメソッドの呼び出しには順序を課しません。ファイナライザは、任意の順序で、あるいは同時に呼び出すことができます。 ( JVM仕様2.17.7する

この私の推論から参照がトポロジカル順にキューイングされているという保証がないこと。

私はそのような保証はありませんだと思います。 (GCは一度に数バイトを見ることができますCPU上で動作するので、それができない)GC自体はRAMの完全かつ即時のビューを持っていません。あなたの例では、基本的な「マークアンドスイープ」GCを仮定すると、可能性があり、AとBは同じマーク相に到達不可能と宣言されること、および特定の順序で一緒にスイープ。トポロジカル秩序を維持することは、おそらく高価になる。

Finalizerとしては、いくつかのクラスローダー関連の魔法を行うだけFinalizableReferenceQueueインスタンスを通じて使用されることを意味しているようです。 Finalizerは、それが機能的に依存するからFinalizableReferenceQueue自体が到達不能になったときを検出する独自の機能を使用します。これはFinalizerを実行するスレッドは、それが終了する必要があることを知っているポイントです。私が理解から、アプリケーションはGCがFRQを取り戻すことができた場合、その後、ファイナライザスレッドが終了すると、すべての参照は、FRQ参照が処理されません「の後に」キューに入れ。これは、トポロジカル順序に依存またはその欠如が、私はこれが問題であるかどうかを決定することはできません。私は、アプリケーションが長い埋め立て参照しているオブジェクトを処理することが重要であるとして、そのようFRQを落とすことになっていないと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top