-2

ガベージ コレクタに関する Java の考え方の章を読んでいて、時々実行されている例を見つけました。しかし、私はその理由を理解できません。

public class Book {

boolean checkedOut = false;

Book(boolean checkOut) {
    checkedOut = checkOut;
}

void checkIn() {
    checkedOut = false;
}

@Override
protected void finalize() {
    if (checkedOut) {
        System.out.println("Error: checked out");
    }
    // Normally, you’ll also do this:
    //super.finalize(); // Call the base-class version
}

public static void main(String[] args) {
    Book novel = new Book(true);
// Proper cleanup:
    novel.checkIn();
// Drop the reference, forget to clean up:
    new Book(true);
// Force garbage collection & finalization:
    System.gc();
    }
}

への呼び出しSystem.gc()は、メモリが不足していない場合でも、オブジェクトのファイナライズを強制する必要があります。

したがって、なぜプログラムはエラーを出力するのでしょうか? 要点がわかりません、分かりやすく説明していただけますか? GC が呼び出されるたびに finalize メソッドも実行されるので、チェックアウト エラーが毎回表示されるはずです。

ありがとう

4

2 に答える 2

3

ドキュメントを読みましたか?

http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#gc%28%29から

gc メソッドを呼び出すということは、Java 仮想マシンが未使用のオブジェクトをリサイクルして、現在占有しているメモリをすばやく再利用できるようにすることを示唆しています。メソッド呼び出しから制御が戻ると、Java 仮想マシンは、破棄されたすべてのオブジェクトからスペースを再利用するために最善を尽くしています。

(私のものを強調)

「この呼び出しの後、ルート化されていないすべてのオブジェクトが回収され、それらのファイナライザーが実行されることが保証されます」とは言いません。GC に、再利用するデータがあるかどうかを確認することをお勧めしますそれ以上はありません。

(またコードがオブジェクトがガベージコレクションされたかどうかではなく、オブジェクトのファイナライザーが実行されたかどうかをチェックすることを示しました)

于 2013-09-14T13:41:22.567 に答える
1

オブジェクトがガベージ コレクションされない(したがって呼び出されない)可能性は十分にありfinalizeます。

これは、オブジェクトが gc の対象とならない場合 ( JVM の存続期間全体を通じて到達可能であるため)、またはオブジェクトが対象となる時点から JVM の実行が停止するまでの間にガベージ コレクションが実際に実行されない場合に発生する可能性があります (これは単純なテストプログラム)。

必ず呼び出されるという保証はありませんfinalize()

注:目的を理解するために実行している場合は問題ありませんが、System.gc()明示的に呼び出すことは避けてください。

免責事項:これが適切な方法であると言っているわけではありません。delay の呼び出しの前に遅延があった場合、作成されたオブジェクトが gc によって検出され、毎回収集される可能性があると考えてみました。

回避策 (動作を保証するものではありません)

Thread.sleep(10000); //try sleeping for a while before giving a call to gc
// Force garbage collection & finalization:
    System.gc();

私の環境では、目的の出力を4回続けて印刷しました。

于 2013-09-14T13:41:37.840 に答える