4

それはあたかもそうであるように思われるでしょう。しかし、誰かがそれを肯定または否定できますか?

関連するものは次のとおりです。

java.lang.OutOfMemoryError をキャッチしていますか?

javaでメモリ不足の例外をキャッチすることは可能ですか?

4

4 に答える 4

5

javaでOutOfMemoryErrorがスローされた後にガベージコレクションが実行されますか?

OOME がスローされる前に確実に実行されます。実際、OOME は通常、割り当て要求を満たすのに十分なスペースを再利用できないことをガベージ コレクターが発見した結果としてスローされます1

OOME がスローされたに実行されるかどうかは、アプリケーションの動作によって異なります。アプリケーションが続行を試みる場合、GC は通常、次回アプリケーションがさらに多くのメモリを要求したときに実行されます ... その継続的な実行で。

1 - 実際、GC がガベージ コレクションに多くの時間を費やしていることを検出した場合に、OOME をスローするように GC を構成することができます。この場合、JVM には十分な量の未割り当てメモリが手元にある可能性があります。


アーロン・ディグラは次のように述べています。

したがって、慎重に設計されたアプリケーションでは、OOME をキャッチして処理することができ、プログラムは生き残り、動作し続けます。

これは事実ですが、2 つの異なる理由から、通常行うべきことではありません。

最初の理由は、スレッドがメモリを割り当てようとする場所ならどこでもOOME がスローされる可能性があることです。その時点でJVMが行っていたものは何でも終了します... OOMEがキャッチされるまで。例えば:

  • スレッドが (ロック下で) 共有データ構造を更新中だった場合、データ構造は半分更新されたままになります。

  • スレッドが他のスレッドに通知する予定だった場合、その通知は発生せず、他のスレッドは待機状態になります。

  • スレッドが OOME をキャッチしなかった場合、スレッドは終了します。他に何も通知されない場合は、アプリケーションが機能しなくなってしまう可能性があります。

問題は、これらの「破損」を検出または予測するのが難しく、回復するのが難しいことです。

2 つ目の理由は、OOME は通常、次のいずれかを示しているためです。

  • 不十分なヒープ メモリで計算を実行しようとしました。OOME から回復しようとすると、同じ問題が再び発生する可能性があります。

  • アプリケーションにメモリ リークがあります。つまり、アプリケーションの一部のデータ構造が「不要な」オブジェクトへの参照を保持しており、それらの再利用を妨げています。OOME から回復しようとしても、何も変わらず、何度も何度も同じ問題に遭遇する可能性があります。

したがって、リカバリが成功するための前提条件は次のとおりです。

  • OOME が JVM 内の重要なものに損傷を与えていないことを知っている、かつ
  • 根本的な原因がまだ存在するため、OOME に再び遭遇することはないことがわかっています

これらは、ほとんどのアプリケーションで満たすのが難しい前提条件です。これらが満たされていない場合、OOME から回復しようとすると、アプリケーションを終了して再起動した場合よりも悪い状態になる可能性が高くなります。

于 2012-11-22T09:36:23.490 に答える
2

あなたの質問が本当に OutOfMemoryErrorに実行されるかどうかである場合:はい。前も走る。OutOfMemoryErrorJVM を終了しません。オブジェクトの割り当てが成功する代わりにスローされ、プログラムが続行されます。JVM は、ガベージ コレクションを含めて続行します。

実際、Tomcat のような一部のフレームワークは、このために設計されています。使用されていないメモリを少し割り当てますOutOfMemoryError。これには、GC を実行し続ける必要があります。

于 2012-11-22T08:58:36.373 に答える