Springでアプリケーションを開発しました。私はスレッドを作成するBeanを持っていますが、実行時にこのスレッドの実行中にJVMはOutOfMemoryError - Java Heap Spaceをスローします。
次の解決法が問題を解決するのに適しているかどうかを聞いてみましょう: スレッドが投げられて以前にスレッドが占有していたメモリを解放した後、別のスレッド(RestartThreadを呼び出します)スレッドは死んでいます(エラーをキャッチせずに)。
1)デッドスレッドのメモリを効果的に解放するガベージコレクタを呼び出します。
2)死んだスレッドの前のインスタンス(死んだスレッドによって使用されたプライベート変数を含み、 'OutOfMemoryError'の生成後もメモリ内に残る)を再起動する、死んだスレッドのコールバック関数run()を呼び出します。
あなたはこのことについてどう思いますか?問題が生じる可能性がありますか?死んだスレッドの以前の再起動を再開する正しい解決策ですか?事前に
おかげで、
--AlucardJava Spring:OutOfMemoryErrorの後でReRunがスレッドを終了しました
答えて
OutOfMemoryError
からのリカバリは、特にマルチスレッド環境では非常に困難であり、多くの場合不可能です。おそらくメモリが足りなくなった理由(漏れている参照やアプリケーションには与えられたメモリよりも多くのメモリが必要です)を調べて、それを修復しようとするのではなく、修正しようとしているはずです。
エラーをスローするスレッドを停止させて再起動させることができたとしても、再開されたスレッドはおそらく最初からすぐにもう一度死んでしまうでしょう。より悪いシナリオでは、根本原因はプログラムの他の部分にある可能性があります。これは、アプリケーション内の他のスレッドが新しいオブジェクトを割り当てようとするのと同じエラーを投げ始め、その結果アプリケーション全体でエラーカスケードが発生し、最終的にはすばらしくクラッシュすることになります。
メモリが唯一の問題ではありません。 OOMEで終了したスレッドが処理の途中で、他のスレッドも使用している共有オブジェクトの状態に触れた場合、アプリケーションの状態はかなり(つまり、矛盾する)ものになります。また、別のスレッドが、終了したスレッドが保持していたモニタ(mutex)を待っていた場合や、それと同様に(wait/notifyなど)、もう一方のスレッドがデッドロックになる可能性があります。ほとんどの場合、アプリケーションが本当に復旧したことを確かめる前に、リカバリロジックを作成し、リカバリが成功したことを確認することは非常に困難です。
返信いただきありがとうございます。私は、OutOfMemoryErrorを内部的に呼び出すことなくスレッドを終了することに同意すると、run()内のオブジェクトによって以前に割り当てられたメモリが解放されている場合よりも、スレッドを再起動することを考える価値があります。関数の実行()。あなたは何を考えていますか? – Alucard8
メモリはあなたの唯一の問題ではありません。 OOMEで終了したスレッドが処理の途中で、他のスレッドも使用している共有オブジェクトの状態に触れた場合、アプリケーションの状態はかなり(つまり、矛盾する)ものになります。また、別のスレッドがモニタ(ミューテックス)を待っていて、終了したスレッドが保持していた、または同様の場合、もう一方のスレッドがデッドロックになる可能性があります。ほとんどの場合、アプリケーションが本当に回復したかどうかを確認する前に、チェックする変数や項目が多すぎるため、回復ロジックの作成とチェックは非常に難しくなります。 – esaj
わかりました。説明のおかげで多くの – Alucard8
はOutOfMemoryError
を防ぐために全力を尽くします。他の選択肢がない場合、つまりGCで削除できるすべてのオブジェクトが既に削除されている場合、JVMによってスローされます。これが起こると、JVMはしばしば正常に終了するためのリソースを持っていません。それは殺され、再び始まるべきです。 OutOfMemoryError
を捕まえていくつかのリソースをリンクしようとしても、これはうまくいかず、少なくとも堅牢には動作しません。
あなたはここを参照してください ダンプあなたがヒープを生成することにより、OOMエラーを持っていない理由を理解しようとすることができます:
をここに答えは、JBoss Application Serverのですが、それは一般的なケースで動作するはずです任意のjavaプロセスのために。
このダンプを解析すると、同じ種類のオブジェクトが多数生成されていることがわかります。
希望はこのことができます
- 1. スレッドの後のコールバック。開始()が終了しましたか?
- 2. すべてのスレッドを終了した後にアクティビティを終了します。
- 3. スレッド終了の問題(C):最後のスレッドが終了しない
- 4. 最初のスレッドが終了した後、どのスレッドがスケジュールされますか?
- 5. EJBシングルトンは - スレッドが終了した後、「トランザクションがアクティブでない」
- 6. 現在のスレッドが終了した後にスレッドを起動する
- 7. FXスレッドがJavaで終了した場合にスレッドを終了する最も効率的な方法
- 8. スレッドが終了した後に文を実行
- 9. Javaスレッドが遅延で終了する
- 10. どのスレッドが同時スレッドで最初に終了しましたか?
- 11. perlスレッドがデタッチした後に終了する
- 12. Xamarin Androidでアプリケーションを終了した後、バックグラウンドサービスが終了する
- 13. C#プログラムが終了した後にコンソールが終了しない
- 14. Mac Appアプリケーションが終了した後にSQLDeveloperがスタックした、プロセスが終了しました
- 15. Javaスレッドはメッセージnullの例外で異常終了します。
- 16. コアJavaマルチスレッド - スレッドが終了していません
- 17. リダイレクト後にRubyスレッドが終了する
- 18. Javaマルチスレッドでスレッドが終了するのを待ちます
- 19. Javaスレッドが警告なしで終了する
- 20. メソッドの終了後にスレッドを実行しますか?
- 21. ブラウザコントロールの終了後のエナンシングメソッドの読み込みが終了しましたか?
- 22. Runtime.getRuntime()。exec()メソッドを完了した後にJavaプロセスを終了します
- 23. Java - Executors.newFixedThreadPoolで実行されたスレッドは決して終了しません。
- 24. ムービーがJMFで終了し、プログラムを終了しました
- 25. 終了したらスレッドを待つ(Android)
- 26. アプリケーションを終了した後にサービスが終了する
- 27. MessageBoxが終了した後の終了プログラム
- 28. スレッドが終了せず、プログラムが終了しない
- 29. メインアクティビティを再開した後にスレッドを強制終了しますか?
- 30. javaの複数の並列スレッドは終了しません
あなたはおそらくあなたが(参照またはアプリケーション単にあなたがそれに与えられてきたよりも多くのメモリを必要とするが漏れるような)メモリが不足する理由を見つけ、それを修正しようとするのではなく、しようとしなければなりませんOOMから修復すること(最高では難しい場合があります) – esaj
これに頼るべきではありません。 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 –