18

finalize()プログラム コードからオブジェクトを呼び出した場合、ガベージ コレクターがこのオブジェクトを処理するときに、 JVMはメソッドを再度実行しますか?

これはおおよその例です:

MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

JVMのガベージ コレクタがオブジェクトに対してメソッドを実行しないようにfinalize()するための明示的な呼び出しはありますか?finalize()m

4

3 に答える 3

30

この簡単なテスト プログラムによると、JVM は明示的に呼び出した場合でも finalize() を呼び出します。

private static class Blah
{
  public void finalize() { System.out.println("finalizing!"); }
}

private static void f() throws Throwable
{
   Blah blah = new Blah();
   blah.finalize();
}

public static void main(String[] args) throws Throwable
{
    System.out.println("start");
    f();
    System.gc();
    System.out.println("done");
}

出力は次のとおりです。


ファイナライズ開始!
ファイナライズ中!
終わり

そこにあるすべてのリソースは、 finalize() を明示的に呼び出すことは決してなく、メソッドを実装することさえほとんどしないと述べています。すべてのリソースを手動で閉じたほうがよいでしょう。

于 2008-08-26T19:23:06.483 に答える
7

ファイナライズの機能を理解するには、ガベージ コレクター (GC) ワークフローを理解する必要があります。.finalize() を呼び出してもガベージ コレクターは呼び出されず、system.gc も呼び出されません。実際、コーダーがファイナライズに役立つのは、オブジェクトの参照を「参照されていない」と宣言することです。

GC は JVM の実行中の操作を強制的に中断させ、パフォーマンスに影響を与えます。操作中、GC はルート オブジェクト (メイン メソッド呼び出し) から開始して、参照されているすべてのオブジェクトをトラバースします。この一時停止時間は、オブジェクトを参照されていないと手動で宣言することで短縮できます。これは、自動実行によってオブジェクト参照が廃止されたことを宣言する操作コストが削減されるためです。finalize() を宣言することにより、コーダーはオブジェクトへの参照を廃止するように設定します。したがって、GC 操作の次の実行時に、GC 実行は操作時間を使用せずにオブジェクトをスイープします。

引用: 「オブジェクトに対して finalize メソッドが呼び出された後、Java 仮想マシンが、まだ終了していないスレッドがこのオブジェクトにアクセスできる手段がなくなったと再び判断するまで、それ以上のアクションは実行されません。ファイナライズの準備ができている他のオブジェクトまたはクラスによって可能なアクションを含み、その時点でオブジェクトは破棄される可能性があります。」 from Java API Doc on java.Object.finalize();

詳細な説明については、javabook.computerwareも確認してください。

于 2013-12-20T15:22:18.623 に答える
2

finalize メソッドは、任意のオブジェクトに対して JVM によって 2 回以上呼び出されることはありません。とにかく、ファイナライズが呼び出されるという保証はないため、ファイナライズに依存するべきではありません。クリーンアップ コードを実行する必要があるために finalize を呼び出す場合は、それを別のメソッドに入れて明示的にすることをお勧めします。

public void cleanUp() {
  .
  .
  .
}

myInstance.cleanUp();
于 2008-08-26T18:59:31.907 に答える