20

JLS を読んでいて、セクション11.1.3 に遭遇しました。私が引用する非同期例外:

ほとんどの例外は、例外が発生したスレッドによるアクションの結果として同期的に発生し、そのような例外が発生する可能性があると指定されたプログラム内のポイントで発生します。対照的に、非同期例外は、プログラムの実行中の任意の時点で発生する可能性がある例外です。

非同期例外は、次の結果としてのみ発生します。

[...]

  • Java 仮想マシンの内部エラーまたはリソース制限により、Java プログラミング言語のセマンティクスを実装できなくなります。この場合、スローされる非同期例外は、VirtualMachineError のサブクラスのインスタンスです。

ログの目的や通知のためにそのような例外をキャッチすることは可能ですか (そのようなことは回復できないと信じているため)? どうすればそのようなことを達成できますか?

4

2 に答える 2

19

このような例外は、他の例外と同じようにキャッチできます。唯一の問題は、それらがプログラムの任意の場所で発生する可能性があるため、確実にキャッチするのが難しいことです。基本的にはrun、すべてのスレッドのmainメソッドとtry..catchブロック内のメソッドをラップする必要がありますが、制御しないスレッド (Swing EDT やタイマーのスレッドなど) に対してはラップできません。

また、JVM が不安定な状態にある可能性があり、さらなる障害につながる可能性があるため、 のサブクラスをキャッチすることErrorは通常はお勧めしません (たとえば、 の場合OutOfMemoryError、例外処理に十分なメモリさえない可能性があります)。Errorただし、ロギングは、私の目に sをキャッチする正当な理由になります。

私の提案する解決策は、キャッチされていない例外ハンドラーをデフォルトの例外ハンドラーとして設定して使用することです。このハンドラーでは、コードのどこにもキャッチされていない場合、すべての例外とエラーを取得し、それらをログに記録することができます。

于 2012-11-22T06:39:55.480 に答える
3

これらの例外 (VirtualMachineError のサブクラス) をキャッチする意味はありません。これは、その時点でプログラムがどの状態にあるかを示す指示がないためです。Doc は仮想マシン エラーについて次のように述べています。

Java 仮想マシンの実装は、内部エラーまたはリソースの制限により、この章で説明するセマンティクスを実装できない場合、クラス VirtualMethodError のサブクラスのインスタンスであるオブジェクトをスローします。この仕様は、内部エラーまたはリソース制限が発生する可能性がある場所を予測できず、いつ報告できるかを正確に規定していません

したがって、OutOfMemoryError または UnknownError に陥ったと仮定すると、それについてできることはあまりありません。また、仮想マシンが正しく機能しないと、プログラムも適切に機能しないため、ユーザーに何の助けも提供できません。ポイント、およびそれが発生する理由は、プログラムが原因で発生したコード エラーではないためです。

于 2012-11-22T06:52:09.960 に答える