「長い」弱参照(短くない)の実用的な例はありますか?
これは内部使用のみですか?
一般的な認識に反してFinalize
、オブジェクトがガベージ コレクションされることはありません。むしろ、ルート化された強力な参照がないことが判明した場合、登録されたファイナライザーは、オブジェクトがすぐにガベージ コレクションされるのを防ぎます。Finalize
代わりに、オブジェクトは、最初の機会にメソッドを実行する必要があるオブジェクトの強く根ざしたリストに追加されます。その場合、オブジェクトへの短い弱参照はすべて無効になりますが、長い弱参照は無効になりません。
特定の順序で分解する必要があるオブジェクトが 2 つ以上ある場合、最後に分解する必要があるオブジェクトが、最初に分解する必要があるオブジェクトへの参照を持つことが役立つ場合があります。これは、前者のオブジェクト (最後に分解されるオブジェクト) が後者のオブジェクト (その前に分解する必要がある) の存続期間を不必要に延長しないように、何らかの形式の弱い参照である必要がありますが、それが短い弱い参照である場合、必要になる直前に使用できなくなります。それを長い弱参照にすることで、その問題を回避できます。
より一般的には、短い弱参照は、オブジェクトが使用可能な状態にあるかどうかのみを知りたい場合に適していますが、長い弱参照は、オブジェクトに関係なくオブジェクトについて知る必要がある場合に適しています。州。別の例として、リモート データベース サーバーが一度に 1 つの接続オブジェクトとしかやり取りできず、その接続オブジェクトには、そのサービスが不要であることをリモート サーバーに通知するファイナライザーがあるとします。接続オブジェクトが破棄され、同じサーバーに再接続しようとした場合、接続マネージャーは次の 3 つのケースに対処できなければなりません。
WeakReference
以前の接続オブジェクトへの参照を保持する がありますが、それでも問題ありません。その場合、コードは単純にそれを使い始める必要があります。
以前の接続オブジェクトのファイナライザが完了まで実行され、リモート サーバーは新しい接続の準備ができています。その場合、コードは単純に新しい接続オブジェクトを作成する必要があります。
GC は、接続オブジェクトが破棄されたことに気付き、ファイナライズをスケジュールしましたが、ファイナライザーはまだ実行されていません。その場合、新しい接続を確立する前に、コードで古い接続を確実にクリーンアップする必要があります。
最初のケースは short で処理できますWeakReference
。2 番目または 3 番目が適用されるかどうかを判断するには、 long が必要ですWeakReference
。ファイナライズのために接続がエンキューされると、接続マネージャはその接続を再利用しようとはしませんが、接続の存在を認識する必要があることに注意してください。