インタビューで次の言葉をもらいました。
オブジェクトの finalize() メソッドの呼び出しは、オブジェクトがガベージ コレクションされる前に行われる最後の処理です。
私は次のように答えなければなりませんでした:
- 真実
- 間違い
選んTrue
だけどダメだった。理由を教えてください。
インタビューで次の言葉をもらいました。
オブジェクトの finalize() メソッドの呼び出しは、オブジェクトがガベージ コレクションされる前に行われる最後の処理です。
私は次のように答えなければなりませんでした:
選んTrue
だけどダメだった。理由を教えてください。
順序は異なります。
http://java.dzone.com/articles/ocajp-7-object-lifecycle-javaを参照してください。
オブジェクトのライフサイクル:
- 作成した
- 使用中 (強く到達可能)
- 見えない
- 到達不能
- 集めました
- ファイナライズ済み
- 割り当て解除
GCが実際にオブジェクトを破棄する前に、オブジェクトに対して実行できる/発生することが実際には他にあるという事実を示唆していると思います。
参照を引用するには:
[...] finalize メソッドは、このオブジェクト を他のスレッドで再び使用できるようにするなど、任意のアクションを実行できます。ただし、ファイナライズの通常の目的は 、オブジェクトが取り消し不能に破棄される前にクリーンアップ アクションを実行することです。たとえば、入出力接続を表すオブジェクトの finalize メソッドは、明示的な I/O トランザクションを実行して、オブジェクトが完全に破棄される前に接続を切断する場合があります。[...]
したがって、この観点から、ファイナライズ プロセスは、GC が破棄する前の最後の処理ではありません。
finalize()
が常に呼び出されるという保証はなく、ガベージ コレクションが実行されるという保証さえありません。
プログラムが (呼び出しによって、System.exit()
または実行中のすべてのスレッドが最後に到達したときに) 終了すると、JVM はただ終了し、すべてをクリーンアップしfinalize()
てすべてのオブジェクトを呼び出すわけではありません。
したがって、絶対に実行する必要があるクリーンアップ タスクをfinalize()
メソッドに配置することはお勧めできません。
オブジェクトを収集する前にガベージコレクターによって呼び出された両方の答えを守ることができると思いますがfinalize()
、アプリケーションが終了する前にそうなるかどうかはわかりません。ガベージ コレクションの対象となるすべてのオブジェクトを収集する必要はありません。finalize()
オブジェクトに対して呼び出されるメソッドに依存することはありません。
DRが既に示したように、順序が間違っています。
オブジェクトが到達不能であることを gc が認識すると、オブジェクトはその状態を収集済みに変更します。
では、この「到達不能」状態が検出される前に、誰がオブジェクトをファイナライズする必要があるのでしょうか? 実際、収集されたオブジェクトにファイナライズのマークを付けるのはガベージ コレクターです (オブジェクトの finalize メソッドがオーバーライドされている場合)。そして、「使用中」など、まだ到達可能なオブジェクトをファイナライズしたくありません。
とにかくいい質問です。なぜなら、あなたは「はい、それは本当です」と言う傾向があるからです。