私はほとんどの答えに同意します。
finalize
またはのいずれかに完全に依存するべきではありません。ShutdownHook
ファイナライズ
finalize()
JVM は、このメソッドがいつ呼び出されるかを保証しません。
finalize()
GC スレッドによって一度だけ呼び出されます。オブジェクトがファイナライズ メソッドから復活した場合、finalize
再度呼び出されることはありません。
アプリケーションには、ガベージ コレクションが呼び出されないライブ オブジェクトがいくつかある場合があります。
Exception
finalizing メソッドによってスローされたものはすべて、GC スレッドによって無視されます
System.runFinalization(true)
およびRuntime.getRuntime().runFinalization(true)
メソッドは、メソッドを呼び出す可能性を高めますが、finalize()
これら 2 つのメソッドは非推奨になりました。これらのメソッドは、スレッドの安全性が欠如し、デッドロックが発生する可能性があるため、非常に危険です。
シャットダウンフック
public void addShutdownHook(Thread hook)
新しい仮想マシンのシャットダウン フックを登録します。
Java 仮想マシンは、次の 2 種類のイベントに応答してシャットダウンします。
最後の非デーモン スレッドが終了するか、exit (同等のSystem.exit
) メソッドが呼び出されると、プログラムは正常に終了します。
仮想マシンは、^C の入力などのユーザー割り込み、またはユーザー ログオフやシステム シャットダウンなどのシステム全体のイベントに応答して終了します。
シャットダウン フックは、単に初期化されているが開始されていないスレッドです。仮想マシンがシャットダウン シーケンスを開始すると、登録されているすべてのシャットダウン フックが不特定の順序で開始され、同時に実行されます。finalization-on-exit が有効になっている場合、すべてのフックが終了すると、呼び出されていないすべてのファイナライザーが実行されます。
最後に、仮想マシンが停止します。exit メソッドの呼び出しによってシャットダウンが開始された場合、非デーモン スレッドと同様に、デーモン スレッドはシャットダウン シーケンス中も実行し続けることに注意してください。
シャットダウン フックもすばやく作業を終了する必要があります。プログラムが exit を呼び出すと、仮想マシンがすぐにシャットダウンして終了することが期待されます。
しかし、Oracleのドキュメントでさえそれを引用しています
まれに、仮想マシンが異常終了する場合があります。つまり、正常にシャットダウンせずに実行を停止する場合があります。
これは、仮想マシンが外部で終了した場合に発生します。たとえば、SIGKILL
Unix のシグナルまたはTerminateProcess
Microsoft Windows の呼び出しで発生します。たとえば、内部データ構造が破損したり、存在しないメモリにアクセスしようとしたりして、ネイティブ メソッドが失敗した場合にも、仮想マシンは中止される可能性があります。仮想マシンが異常終了した場合、シャットダウン フックが実行されるかどうかは保証されません。
結論:ブロックを適切に使用し、ブロックtry{} catch{} finally{}
内の重要なリソースを解放し finally(}
ます。finally{}
ブロック、キャッチ、Exception
およびThrowable
.