12

EclipseでJavaプログラムを実行しているときとコマンドラインから実行しているときにThreadPoolExecutorの動作が異なる理由を調査している間はどうでしょうか。非常に奇妙なOutOfMemoryError(max mem = 256 Mb)をスローするテストを作成しました

class A {
    byte[] buf = new byte[150_000_000];

    protected void finalize() {
        int i = 1;
    }
}

A a1 = new A();
a1 = null;
A a2 = new A();

コメントアウトするint i = 1と、テストが機能します。私が理解している限り、finalize空の場合、HotSpotは単にそれを無視します。finalizeしかし、1つの実質的に空の呼び出しでGC / JVMを壊すにはどうすればよいでしょうか?

4

1 に答える 1

9

しかし、1つの空のファイナライズ呼び出しでGC / JVMを中断するにはどうすればよいでしょうか?

ファイナライザーがある場合、オブジェクトは、そうでない場合よりも1ラウンド多くのガベージコレクションに耐えます(オブジェクト自体は、ファイナライズされるまで存続する必要があるため)。したがって、ファイナライザーを備えた大きなオブジェクトがある場合、ファイナライザーOutOfMemoryErrorがない場合には自然に発生することになります。

このコードでは:

A a1 = new A();
a1 = null;
A a2 = new A();

... GCは、2番目のを割り当てるのに十分なメモリを見つけようとするために、最後の行でトリガーしますAA残念ながら、ファイナライザーがまだ実行されていないため、最初の(およびそれが参照する配列)をガベージコレクションすることはできません。ファイナライザーが完了するまで待機せず、ガベージコレクションを再試行します-スローするだけOutOfMemoryErrorです。

于 2012-12-25T12:27:01.380 に答える