OutOfMemoryError の後、JVM は終了しますか? そうでない場合、なぜですか?リソースを取り戻そうとしますか?それとも他に理由がありますか?
5 に答える
OutOfMemoryError は JVM を終了しません。
キャッチされない場合は、エラーが開始されたスレッドを終了します。もちろん、OutOfMemoryErrors も引き起こさない限り、他のスレッドは正常に実行され続けます。
すべてのスレッドが終了するか、残りのすべてのスレッドがデーモン スレッドになった後でのみ、JVM は終了します。
終了する必要がないため、JVM を終了しません。JVM の終了は非常に極端な操作であり、簡単には実行できません。
取得するものがないため、リソースを取得しようとしません。OOME がスローされる理由は、すべてのリソースが使用されているため、JVM がリソースを取得できないためです。他にできることはすべてすでに行っています。
最も多くのメモリを消費するスレッドで OOME がスローされるとは限らないことを覚えておく必要があります。スレッドはすべてのメモリを消費し、「1 バイトだけ」を割り当てようとする別のスレッドに処理を譲ることができます。これはもちろん失敗し、1 バイトを割り当てようとしたスレッドは OOME によって中断されます。これが、OOME からの回復がほぼ不可能な理由です。
JVM は、(他の例外またはエラーと同様に) どこにもキャッチされず、デーモン スレッドである他のスレッドがない場合に終了します。
OutOfMemoryError
がキャッチされる可能性があり、アプリケーションは、エラーのログ記録からその計算の破棄まで、または通常どおり続行するまで、エラー処理を試行できるため、すぐには終了しません。
後者は、エラーが発生したときに危険であると見なされますが、問題なく実行できることがよくあります。これは、OutOfMemoryError
がスローされたポイントとキャッチされたポイントの間で多くのオブジェクトが範囲外になる可能性があり、ガベージ コレクションによって解放されて動作する新しいメモリをプログラムします。OutOfMemoryError
ある特定の計算で使用可能なメモリよりも多くのメモリが必要になり、その後アプリケーションが別の処理を行ったためにエラーが発生した場合は、問題ありません。
それは、そのエラーを処理するかどうかによって異なります。そうしないと、アプリケーションとそれを含む現在のスレッドが終了します。このスレッドがたまたま最後に実行されていたスレッド (ほとんどの場合、現在のアプリケーションのメイン スレッド) である場合、JVM も終了します (ただし、終了する前に何らかのログ記録やメモリ ダンプの作成などを行う場合があります)。
エラーを処理する場合は、通常、JVM を停止する前に、少しだけクリーンアップを試みます。ほとんどの場合、から回復しようとするのは悪い考えOutOfMemoryError
です。詳細については、こちらを参照してください: Can the JVM recovery from an OutOfMemoryError without a restart
一般に、JVM は最後の非デーモン スレッドが終了したときにのみ終了します。OutOfMemoryError またはその他の種類のエラーまたは例外をスローすると、最後の非デーモン スレッドがキャッチされない場合に存在する可能性があります。
ただし、エラーが捕捉されて再スローされない場合、または別の非デーモン スレッドが実行されている場合、JVM は終了しません。つまり、プログラムを終了させる特定のエラーについて特別なことは何もありません。
資格は2つ
- System.exit() は JVM のシャットダウンを開始し、キャッチできません。複数のスレッドを使用しても違いはありません。
- ThreadDeath エラーは、デフォルトでは出力されないという点で特別です。それ以外の場合は、他のエラーと同じように動作します。
エラーを処理してコードを続行することはできますが、メモリが使用できないため、これ以上オブジェクトを作成できないというエラーがスローされますが、現在作成されているオブジェクトのみで生き残る必要があります。 、またはもう必要のないものを解放または無効にすることができます。
PS:しかし、そのようなエラーを処理して続行するための推奨される方法ではありません