9

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

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

ウィーク/ファントム参照領域から私が知っているすべての通知メカニズムは、通知はある時点で発生すると述べているだけですが、これがいつ発生するかについての保証はありません...

4

7 に答える 7

13

要するに、違います。

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

于 2008-10-16T13:33:47.807 に答える
4

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

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

于 2008-10-16T13:34:53.750 に答える
4

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

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

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

于 2008-10-17T15:47:08.567 に答える
2

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

たとえば、HandleManager を呼び出すサービスでその問題を解決できたとしても、HandleManager はオブジェクトへの新しい参照を作成してハンドラーに渡す必要があります。次に、ハンドラーは次のいずれかを行うことができます。または (b) 参照を解放します。これは、最後の参照が再度解放されたことを意味します。これは、ハンドラーを再度呼び出す必要があることを意味します....

于 2008-10-16T13:57:22.300 に答える
2

ファイルなどの外部リソースを管理する必要がある場合、Java でできる最善の方法は close() 関数です (名前は何でも構いません)。finalize() を「ベルトとサスペンダー」の保険として使用できますが、タイミングは予測できません。したがって、防御の主なラインは close() 関数である必要があります。

私の回答を参照してくださいなぜ finalize() を実装しますか?

于 2008-10-16T15:37:29.413 に答える
0

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

于 2008-10-16T15:15:06.183 に答える
-1

オブジェクトをオーバーライドできますfinalize()が、他の人が言及した理由により問題があります。

特定の例では File.deleteOnExit()、VM が終了するとファイルが削除されるようなものを使用して調べることができます。

于 2008-10-16T14:34:28.963 に答える