例外のスタックトレースが途切れる

元記事最終更新:2007/04/19

概要

Sun Java VMに含まれる、HotSpot Servet VMでアプリケーションを実行する際、たまに例外のスタックトレースが省略されてしまう件に関して記述。

現象

Sun Java SE 1.4.1_08 のHostSpot Server VMで確認。
同じ箇所繰り返しNullPointerExceptionを発生するコードがあった際、何度目かの例外発生後、NullPointerExcetpionインスタンススタックトレースが含まれなくなった。

このため、例外発生時の原因特定が困難となってしまった。

原因

HotSpotVMは、実行時最適化の一環として、繰り返し出力される一部の組み込み例外については、都度例外インスタンスを生成せず、同じインスタンスを使い回すことによってインスタンス生成コストを抑えるという処理を行っている。

この使いまわされる例外インスタンスは、他所でthrowされた例外の情報が混入しないよう、スタックトレースそのものを省略する。

このため、例外発生箇所がHotSpotVMによって最適化されると、以降発生する例外にはスタックトレースが含まれないように見えてしまう。

対応

JavaVM起動時、以下のオプションを付加することにより、上記の例外に対する最適化処理を無効とすることができる。

 -XX:-OmitStackTraceInFastThrow

この設定によるリスクとしては、NullPointerExceptionの生成コストが若干大きくなることが挙げられる。が、NullPointerExceptionの生成コストが全体のパフォーマンスに影響を与えるような状況は、つまりNullPointerExceptionが大量発生しているということであり、そもそもアプリケーションの設計自体を見直さなければならない状況であるので、あまり気にする必要はないんじゃないかと。