[解決済み] java.lang.OutOfMemoryErrorをキャッチする?
質問
ドキュメンテーション
について
java.lang.Error
は言う。
Error は Throwable のサブクラスで、合理的なアプリケーションがキャッチしようとすべきではない深刻な問題を示します。
しかし
java.lang.Error
のサブクラスである
java.lang.Throwable
のサブクラスであり、このタイプのThrowableをキャッチすることができます。
この種の例外をキャッチするのは良くないというのは理解できました。私の理解では、もしキャッチすることにした場合、キャッチハンドラは自らメモリを確保してはいけないと思います。そうでなければ
OutOfMemoryError
が再びスローされます。
そこで質問なのですが
-
をキャッチする際の現実的なシナリオはありますか?
java.lang.OutOfMemoryError
をキャッチするのは良いアイデアでしょうか? -
をキャッチすることにしたら
java.lang.OutOfMemoryError
をキャッチすることにした場合、キャッチハンドラがそれ自身でメモリを割り当てないことを確認するにはどうすればよいでしょうか(何かツールやベストプラクティスがあれば教えてください)。
どのように解決するのですか?
をキャッチしたいシナリオはいくつもあります。
OutOfMemoryError
をキャッチしたい場合がありますが、私の経験では(WindowsとSolaris JVM上で)、非常にまれにしか
OutOfMemoryError
はJVMへの死刑宣告です。
をキャッチする正当な理由は1つだけです。
OutOfMemoryError
をキャッチする良い理由はただ一つで、それは優雅に終了し、リソースをきれいに解放し、失敗の理由をできる限り記録することです(もしそうすることがまだ可能であるならば)。
一般に
OutOfMemoryError
は、ヒープの残りのリソースで満たすことができないブロックメモリの割り当てが原因で発生します。
が発生すると
Error
が投げられたとき、ヒープは失敗した割り当ての前と同じ量の割り当てられたオブジェクトを含み、今、クリーンアップのために必要とされるかもしれないより多くのメモリを解放するために、ランタイムオブジェクトへの参照を削除する時間です。これらのケースでは、続けることが可能かもしれませんが、JVMが修復可能な状態であることを100%確実にすることはできないので、それは間違いなく悪い考えでしょう。
デモでは
OutOfMemoryError
は、JVMがキャッチブロック内でメモリ不足であることを意味しません。
private static final int MEGABYTE = (1024*1024);
public static void runOutOfMemory() {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
for (int i=1; i <= 100; i++) {
try {
byte[] bytes = new byte[MEGABYTE*500];
} catch (Exception e) {
e.printStackTrace();
} catch (OutOfMemoryError e) {
MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
long maxMemory = heapUsage.getMax() / MEGABYTE;
long usedMemory = heapUsage.getUsed() / MEGABYTE;
System.out.println(i+ " : Memory Use :" + usedMemory + "M/" +maxMemory+"M");
}
}
}
このコードの出力。
1 : Memory Use :0M/247M
..
..
..
98 : Memory Use :0M/247M
99 : Memory Use :0M/247M
100 : Memory Use :0M/247M
クリティカルなものを実行する場合、私は通常
Error
をキャッチし、それを syserr に記録し、選択したロギング フレームワークを使ってそれを記録し、それからリソースを解放し、きれいな方法で終了します。起こりうる最悪の事態は何でしょうか?JVMはとにかく死につつあり(あるいはすでに死につつあり)、そして
Error
をキャッチすることによって、少なくともクリーンアップのチャンスがあります。
注意点は、クリーンアップが可能な場所でのみ、この種のエラーの捕捉を目標としなければならないことです。空白にしないこと
catch(Throwable t) {}
のような無意味なことはしないでください。
関連
-
スレッド "main" での例外 java.lang.ArrayIndexOutOfBoundsException:5 エラー
-
BindException: アドレスはすでに使用中です:バインドエラー解決
-
JDK8 の Optional.of と Optional.ofNullable メソッドの違いと使い方を説明する。
-
コンストラクタDate()が未定義である問題
-
htmlとwordの相互変換の実装(画像あり)
-
linux ant Resolve error: main class not found or couldn't be loaded org.apache.tools.ant.launcher.
-
swagger2 モデルが表示されない モデルが見つからない @ApiModel アノテーションが表示されない問題
-
[解決済み] java.lang.OutOfMemoryError "に対処する。PermGen space "エラーに対処する
-
[解決済み] エラー java.lang.OutOfMemoryError: GCオーバーヘッドの制限を超えました
-
[解決済み] java.lang.OutOfMemoryError" の対処法。Java heap space "エラーの対処方法を教えてください。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
XMLファイル操作時のjava.util.NoSuchElementExceptionを解決する方法。
-
アクセス制限です。タイプ 'Application' は API ではない(必要なライブラリに制限がある)。
-
メモ帳でJavaプログラムをコンパイルして実行すると、Could not find or load main class ...というエラーが表示される。解決方法
-
強制型変換について
-
java -jarコマンドでパッケージを実行すると、無効または破損したjarfile xxxx.jarが表示される。
-
Java Notes 005_この行に複数のマーカーがある - キーを変数に解決できない - シンタックスエラー、ins
-
SpringBoot 起動エラー java.nio.charset.MalformedInputException: 入力長 = 2 解決
-
maven レポート エラー 解決不可能な親POM
-
htmlとwordの相互変換の実装(画像あり)
-
[解決済み] java.lang.Errorをキャッチするタイミングは?