3

一般的なアドバイスは、特別な状況を除き、java.lang.Error をキャッチしないことです。Throwable をキャッチするのは悪い習慣ですか? を参照してください。例えば。

私の状況では、時々メモリ不足になり、java.lang.OutOfMemoryError をスローするプログラムがあります。これから回復することはありませんが、それが起こったことを知りたいので、ログに何かがあり、ゼロ以外の終了コードが表示されることを望みます。では、このようなことはお勧めですか?

public static void main(String[] args)
{
    try
    {
        ...
    }
    catch (Exception e)
    {
        e.printStackTrace();
        System.exit(1);
    }
    catch (OutOfMemoryError e)
    {
        e.printStackTrace();
        System.exit(1);
    }
}

別のプログラムも同様ですが、すべてのメモリを消費している特定のスレッドである可能性があります。この場合、そのスレッドが終了すると、処理を続行できます。ここでも、ログを確認し、最終的にゼロ以外の終了コードを取得するだけです。そのスレッド実行メソッドで OutOfMemoryError をキャッチする必要がありますか?

4

4 に答える 4

7

コール スタックの最上部に例外バリアを配置し、すべてThrowableの をキャッチしてログに記録することには、完全な意味があります。サーバー側のコードでは、これが実際の標準です。そのレベルでのみキャッチすることを確認し、それより低いレベルではキャッチしない場合OutOfMemoryError、システムに害を及ぼさない可能性が非常に高くなります。コール スタックが巻き戻されると、リクエストを処理するために作成されたすべてのオブジェクトが到達不能になります。OOME は、システムに最も強いメモリ プレッシャを与えていたスレッドで正確に発生した可能性が非常に高いため、そのメモリはすべて回収され、システムの残りの部分は再び呼吸できるようになります。

はい、技術的には、ブロック内で OOME を取得する可能性が常にありfinally、リソース リークまたはそれ以上の原因となります。または、長寿命のグローバル構造を変更し、その不変条件を壊していたコードの内部ですが、実際にはほとんどありません。

OOME のポリシーを決定するときは、アプリケーションが多かれ少なかれその安定性を低下させる可能性のある多くの予測不可能な要因の影響を受けることに留意してください。OOME はそのスペクトルの別のポイントに過ぎず、通常、そのリスクへの影響は特に高くありません。

于 2013-01-17T10:30:01.900 に答える
2

それをキャッチするのは一般的ですが、スレッドの最高レベルでのみです。最も簡単な方法は、uncaughtexception ハンドラを使用することです。例外がスローされたときに呼び出される関数です。その時点でログに記録し、アプリケーションを終了する理由をユーザーに伝えることができます。

于 2013-01-17T10:29:22.807 に答える
0

上記の例では、プログラムのシャットダウン方法を制御できるようにすることをお勧めします。このエラーをキャッチしないと、他のスレッドが引き続き正しく実行されない可能性があります (エラーは 1 つのスレッドでのみスローされます)。また、呼び出し元のシェルがチェックできるときに終了コードも提供されます。このエラーには別の終了コードを使用します。

一般に、OOME は回復可能であることが保証されていませんが、プログラムがシャットダウンされることも保証されていません。

于 2013-01-17T10:59:26.043 に答える
0

一般的なルールは次のとおりです。例外は、適切に反応する能力が最も高いモジュールによってキャッチされるべきです。現在のメソッドが何をすべきかわからない場合は、main() または run() メソッドに到達するまで、例外を通過させる必要があります。これらのメソッドは、より有能なメソッドがあることを期待できないため、キャッチしてログに記録したり、水を流したりすることができます。

于 2013-01-17T10:35:41.483 に答える