2012-02-11 34 views
0

Springでアプリケーションを開発しました。私はスレッドを作成するBeanを持っていますが、実行時にこのスレッドの実行中にJVMはOutOfMemoryError - Java Heap Spaceをスローします。
次の解決法が問題を解決するのに適しているかどうかを聞いてみましょう: スレッドが投げられて以前にスレッドが占有していたメモリを解放した後、別のスレッド(RestartThreadを呼び出します)スレッドは死んでいます(エラーをキャッチせずに)。
1)デッドスレッドのメモリを効果的に解放するガベージコレクタを呼び出します。
2)死んだスレッドの前のインスタンス(死んだスレッドによって使用されたプライベート変数を含み、 'OutOfMemoryError'の生成後もメモリ内に残る)を再起動する、死んだスレッドのコールバック関数run()を呼び出します。

あなたはこのことについてどう思いますか?問題が生じる可能性がありますか?死んだスレッドの以前の再起動を再開する正しい解決策ですか?事前に

おかげで、
--AlucardJava Spring:OutOfMemoryErrorの後でReRunがスレッドを終了しました

+2

あなたはおそらくあなたが(参照またはアプリケーション単にあなたがそれに与えられてきたよりも多くのメモリを必要とするが漏れるような)メモリが不足する理由を見つけ、それを修正しようとするのではなく、しようとしなければなりませんOOMから修復すること(最高では難しい場合があります) – esaj

+0

これに頼るべきではありません。 http://stackoverflow.com/questions/3058198/can-the-jvm-recover-from-an-outofmemoryerror-without-a-restartおよびhttp://stackoverflow.com/questions/2679330/catching-java-langを参照してください。 -outofmemoryerror/2679410#2679410 –

答えて

1

OutOfMemoryErrorからのリカバリは、特にマルチスレッド環境では非常に困難であり、多くの場合不可能です。おそらくメモリが足りなくなった理由(漏れている参照やアプリケーションには与えられたメモリよりも多くのメモリが必要です)を調べて、それを修復しようとするのではなく、修正しようとしているはずです。

エラーをスローするスレッドを停止させて再起動させることができたとしても、再開されたスレッドはおそらく最初からすぐにもう一度死んでしまうでしょう。より悪いシナリオでは、根本原因はプログラムの他の部分にある可能性があります。これは、アプリケーション内の他のスレッドが新しいオブジェクトを割り当てようとするのと同じエラーを投げ始め、その結果アプリケーション全体でエラーカスケードが発生し、最終的にはすばらしくクラッシュすることになります。

メモリが唯一の問題ではありません。 OOMEで終了したスレッドが処理の途中で、他のスレッドも使用している共有オブジェクトの状態に触れた場合、アプリケーションの状態はかなり(つまり、矛盾する)ものになります。また、別のスレッドが、終了したスレッドが保持していたモニタ(mutex)を待っていた場合や、それと同様に(wait/notifyなど)、もう一方のスレッドがデッドロックになる可能性があります。ほとんどの場合、アプリケーションが本当に復旧したことを確かめる前に、リカバリロジックを作成し、リカバリが成功したことを確認することは非常に困難です。

+0

返信いただきありがとうございます。私は、OutOfMemoryErrorを内部的に呼び出すことなくスレッドを終了することに同意すると、run()内のオブジェクトによって以前に割り当てられたメモリが解放されている場合よりも、スレッドを再起動することを考える価値があります。関数の実行()。あなたは何を考えていますか? – Alucard8

+0

メモリはあなたの唯一の問題ではありません。 OOMEで終了したスレッドが処理の途中で、他のスレッドも使用している共有オブジェクトの状態に触れた場合、アプリケーションの状態はかなり(つまり、矛盾する)ものになります。また、別のスレッドがモニタ(ミューテックス)を待っていて、終了したスレッドが保持していた、または同様の場合、もう一方のスレッドがデッドロックになる可能性があります。ほとんどの場合、アプリケーションが本当に回復したかどうかを確認する前に、チェックする変数や項目が多すぎるため、回復ロジックの作成とチェックは非常に難しくなります。 – esaj

+0

わかりました。説明のおかげで多くの – Alucard8

2

OutOfMemoryErrorを防ぐために全力を尽くします。他の選択肢がない場合、つまりGCで削除できるすべてのオブジェクトが既に削除されている場合、JVMによってスローされます。これが起こると、JVMはしばしば正常に終了するためのリソースを持っていません。それは殺され、再び始まるべきです。 OutOfMemoryErrorを捕まえていくつかのリソースをリンクしようとしても、これはうまくいかず、少なくとも堅牢には動作しません。

1

あなたはここを参照してください ダンプあなたがヒープを生成することにより、OOMエラーを持っていない理由を理解しようとすることができます:

Link

をここに答えは、JBoss Application Serverのですが、それは一般的なケースで動作するはずです任意のjavaプロセスのために。

このダンプを解析すると、同じ種類のオブジェクトが多数生成されていることがわかります。

希望はこのことができます

+0

提案をありがとう、それは非常に便利です。問題は、私はJVMにもっと引数を渡さないようにしているので、私は外部から問題を解決しようとしているということです。 – Alucard8

+0

私は、問題の根本原因を解決するのに役立つ一時的なチェックとしてこのオプションを考えました。 「再起動」のようなものは回避策であり、問​​題を解決することはできませんが、復旧に役立ちます。 –

+0

これは本当です。返信ありがとう – Alucard8

関連する問題