質問

特定のオブジェクトへの最後の参照が解放されたときに正確に呼び出されるハンドラーを作成する方法はありますか?

例としては、物理データファイルによってバッキングされるオブジェクトがあり、オブジェクトが参照されなくなったら、ファイルを閉じて名前を変更する必要があります。 「close」を明示的に呼び出さずにこれが可能であると便利です。そのオブジェクトのメソッド。

Weak / Phantom参照領域から認識しているすべての通知メカニズムは、ある時点で通知が発生することのみを述べていますが、これがいつ発生するかについての保証はありません...

役に立ちましたか?

解決

要するに、いいえ。

Java仕様では、最後の参照がいつリリースされたかを明確に知ることができません。 JVM実装(および最適化)はこれに依存します。フックはありません。

他のヒント

私の理解から、「デストラクタ」を見つけるためにしばらく探しました。 Javaオブジェクトの場合、最後の参照を失ったことを知る方法はありません。 Javaはオブジェクトへの参照を追跡しますが、パフォーマンス上の理由により、ガベージコレクション中にのみこの情報を更新します。

最も近いものは、ガベージコレクション中に呼び出されるfinalizeメソッドですが、それでも呼び出されるという保証はありません。

WeakReferenceはあなたが望むことをしていると思います。 WeakReferenceは、弱く到達可能になるとすぐにReferenceQueueに入れられます(つまり、すべての強い参照がなくなります)。

Ethan Nicholas によるこの記事を参照してください。

シャットダウン時にReferenceQueueに到達しない参照がある場合は、作成されたすべてのオブジェクトのリストを保持します(WeakReferencesまたはPhantomReferencesを使用)。未処理の参照がないかリストをチェックし、必要なアクションを実行するシャットダウンフックを追加します。

問題は、"オブジェクトへの参照を保持するものなしでこれをどのように実装しますか?"

その問題に合格できたとしても、たとえば、サービスでHandleManagerを呼び出す場合、HandleManagerはハンドラーに渡すためにオブジェクトへの新しい参照を作成する必要があります。次に、ハンドラーは(a)参照を保存することができます。これにより、参照されていないオブジェクトを破棄することを期待していたHandleManagerが混乱します。または(b)参照を解放します。これは、最終参照が再び解放されたことを意味します。つまり、ハンドラーを再度呼び出す必要があります。...

ファイルなどの外部リソースを管理する必要がある場合、javaでできることはclose()関数(選択した名前)です。 finalize()を「ベルトとサスペンダー」として使用できます。保険契約、しかしそれは予測不可能なタイミングを持っています。したがって、主な防衛線はclose()関数である必要があります。

私の回答をご覧くださいなぜfinalize()を実装するのですか?

これはJavaでは実行できません-私が知る限り、参照カウントガベージコレクターが必要です。オブジェクトの存続期間中は開いたままにするのではなく、必要に応じてオブジェクトの物理データファイルを開いたり閉じたりすることを検討しましたか?

オブジェクト内で finalize()をオーバーライドすることができますが、他の人が言及している理由で問題があります。

特定の例については、 File.deleteOnExit() 。VMが終了するとファイルが削除されます。

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