先のエントリで情報のあったThreadの頓死の話。
きしだのはてな様が元ネタです。
気になったので私も検証してみました。
- Windows Vista
- JDK 1.6.0_1
public static void main(String[] args) {
// UncaughtExceptionHandlerで例外の捕捉を試みる
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Thread : " + t);
e.printStackTrace();
}
});
// 以下、Thread頓死の検証コード
final List<List> l = new ArrayList<List>();
new Thread("TestThread") {
public void run() {
for (;;)
l.add(new ArrayList());
}
}.start();
}
特別の工夫はないのですが、UncaughtExceptionHandlerを利用してそもそもthrowされているのかを検証してみました。
結果、UncaughtExceptionHandlerへのコールはされず。
メモリがなくてthrowする最中に落ちているではないでしょうか。
Errorの取り扱い
Javaにはチェック例外(Exceptionとそのサブクラス)と未チェック例外(RuntimeExceptionとそのサブクラス)がありますが、
もうひとつ、エラー(Errorとそのサブクラス)というものがあります。
Errorのjavadocでは以下のように書かれています。
通常のアプリケーションであればキャッチすべきではない重大な問題を示します。そうしたエラーの大部分は異常な状態です。
(中略)
メソッドは、そのメソッドを実行する際にスローされる可能性はあってもキャッチはされない Error のサブクラスを、throws 節で宣言する必要はありません。このようなエラーは、絶対に起きてはならない異常な状態であるためです。
具体的にどんなものがあるか、幾つか挙げてみましょう。
ClassFormatError |
Java 仮想マシンがクラスファイルを読み込もうとして、ファイルが壊れていると判断した場合、またはクラスファイルとして解釈できない場合にスローされます。 |
NoClassDefFoundError |
通常のメソッド呼び出し、あるいは new 式を使った新しいインスタンスの生成で、Java 仮想マシンまたは ClassLoader インスタンスがクラス定義をロードしようとしたが、クラス定義が見からない場合にスローされます。 |
OutOfMemoryError |
メモリー不足のために Java 仮想マシンがオブジェクトを割り当てることができず、ガベージコレクタによっても使用可能なメモリーをこれ以上確保できない場合にスローされます。 |
StackOverflowError |
アプリケーションでの再帰の回数が多すぎてスタックオーバーフローが起こる場合にスローされます。 |
他にもあるのですが、多くは実行時の環境といったどうにもならない、続行不可能な状態で発生するようになっています。
ErrorもThrowableインターフェースを継承していますから、try - catchで捕捉できることはできますが、
先のjavadocの説明にあるとおり、catchしないことが推奨されます。
投稿日時 : 2007年9月21日 13:48