5.10.1 -XX:+HitachiLocalsInThrowableオプションが指定されている場合
java.lang.Throwable.printStackTraceメソッドで出力されるスタックトレース情報の1スタックフレーム情報ごとに,そのスタックフレームに対応するメソッド内のローカル変数情報が挿入されて出力されます。
- 〈この項の構成〉
(1) 標準の形式および簡易出力フォーマットでの出力例
ローカル変数を出力するための機能として,-XX:+HitachiLocalsInThrowableオプションだけを指定している場合の出力例です。
Javaプログラムの例と,それに対するスタックトレース内のローカル変数情報の出力例を示します。
Javaプログラムの例1
class Example1 { public static void main(String[] args) { Example1 e1 = new Example1(); Object obj = new Object(); e1.method(1, 'Q', obj); // e1.methodメソッドを実行します(5行目)。 } void method(int l1, char l2, Object l3) { float l4 = 4.0f; boolean l5 = true; double l6 = Double.MAX_VALUE; Object[] l7 = new Object[10]; try { <例外発生!> // methodメソッドの処理内で例外が発生した場合の処理です(15行目)。 } catch (Exception e) { e.printStackTrace(); // スタックトレース情報を出力します(17行目)。 } } }
出力例を次に示します。
この例は,Javaプログラムの例1の5行目で実行したe1.methodメソッドの処理内で例外が発生したときに,17行目のe.printStackTraceメソッドによって出力されるスタックトレース情報です。
出力内容について説明します。
-
スタックトレースを出力する処理を実行したメソッドの情報が出力されます。この例では,javaプログラム1の15行目で例外が発生したときのスタックトレース情報が出力されることを示しています。
-
ローカル変数情報として,インスタンスメソッドの呼び出しの対象になるオブジェクトについての情報が出力されます。この例の場合は,Javaプログラムの例1の3行目で作成したExample1クラスのオブジェクトのクラス名とアドレスが出力されます。
-
ローカル変数情報として,methodメソッドの引数として指定されたローカル変数の値についての情報が出力されます。変数名の後ろの[arg*]は,何番目のメソッド引数かを示す情報です。Javaプログラムの例1の5行目でe1.methodメソッドを実行したときに指定された値が出力されます。
なお,l1およびl2は基本型(int型およびchar型)の変数なので実際の値が出力されます。l3はjava.lang.Objectクラス型の変数なので,アドレスで出力されます。
-
ローカル変数情報として,methodメソッド内のローカル変数のうち,メソッド引数として指定した以外のローカル変数の値についての情報が出力されます。
なお,l4〜l6は基本型(float型,boolean型およびdouble型)の変数なので実際の値が出力されます。l7はjava.lang.Objectクラス型の変数なので,アドレスで出力されます。
次に,-XX:+HitachiLocalsSimpleFormatオプションを指定した場合の,簡易出力フォーマットでの出力例を次に示します。なお,出力内容の説明は,標準の形式と同じです。
また,javacコマンド実行時に,-gオプションまたは-g:varsオプションを指定しなかった場合,ローカル変数情報がないため,出力内容が次のように制限されます。これらは,nativeメソッドを実行した場合も同様です。
-
出力できるローカル変数が,メソッドに渡される引数とインスタンスメソッド呼び出し対象オブジェクト(this)だけになります。
-
メソッドに渡される引数は,変数名が出力されません。引数番号だけが出力されます。
-
nativeメソッドの場合,ローカル変数の値としてnativeメソッドを呼び出した時点での値が出力されます。nativeメソッドの実行結果を反映した出力結果にはなりません。
ローカル変数情報がない場合の,Javaプログラムの例1に対する出力例を次に示します。ここでは,簡易出力フォーマットでの出力例を示します。
図5-3に比べて,次の違いがあります。
-
メソッドに渡される引数(l1〜l3)の変数名が出力されません。
-
メソッド呼び出し時点の値が出力されるため,メソッド内で設定されたローカル変数についての情報(l4〜l7)が出力されません。
(2) クラスまたは配列型の変数を文字列として出力する場合の出力例
出力するローカル変数がクラスまたは配列型の場合,アドレスだけの値表現ではトラブルシューティングに必要な情報が取得できない場合があります。このとき,-XX:HitachiCallToStringオプションの指定をしておくと,クラスまたは配列型の変数の値を文字列で取得できます。オプションには,適用範囲として,minimalまたはfullが指定できます。
-XX:HitachiCallToString=minimalオプションが指定されている場合は,java.langパッケージ内のクラスのうち,String,StringBuffer,Boolean,Byte,Character,Short,Integer,Long,Float,またはDoubleが対象になります。-XX:HitachiCallToString=fullオプションが指定されている場合は,すべてのクラスが対象になります。
次に,Javaプログラムの例と,-XX:HitachiCallToStringオプションが指定されている場合の出力例を示します。なお,ここでは簡易出力フォーマットで示します。
Javaプログラムの例2
class Example2 { public static void main(String[] args) { Example2 e2 = new Example2(); e2.method();// e2.methodメソッドを実行します(4行目)。 } void method() { String l1 = "local 1"; StringBuffer l2 = new StringBuffer(l1); l2.append(" + local 2"); Boolean l3 = new Boolean(false); Character l4 = new Character('X'); Long l5 = new Long(Long.MIN_VALUE); Object l6 = new Thread(); Object[] l7 = new Thread[10]; try { <例外発生!> // methodメソッドの処理内で例外が発生した場合の処理です(18行目)。 } catch (Exception e) { e.printStackTrace(); // スタックトレース情報を出力します(20行目)。 } } public String toString() { return "I am an Example2 instance."; } }
-XX:HitachiCallToString=minimalオプションを指定した場合の出力例を次に示します。
この例は,Javaプログラムの例1の4行目で実行したe2.methodメソッドの処理内で例外が発生したときに,20行目のe.printStackTraceメソッドによって出力されるスタックトレース情報です。
出力内容について説明します。
-
クラス型のローカル変数のうち,文字列を出力する適用対象のクラスの型のローカル変数情報です。アドレスに続いて,文字列に変換した値が出力されます。
-
クラス型のローカル変数のうち,文字列を出力する適用対象外のクラスの型のローカル変数情報です。アドレスだけが出力されます。
次に,-XX:HitachiCallToString=fullオプションを指定した場合の出力例を次に示します。
図5-5に比べて,次の違いがあります。
-
minimalを指定した場合に適用対象外のクラスだったjava.lang.Objectクラスおよびjava.lang.Objectクラスの配列のローカル変数(l6およびl7)に対しても,文字列が出力されます。
ただし,次の場合は,文字列は出力されないで,アドレスだけが出力されます。
-
ローカル変数の値がnullだった場合
-
文字列で出力するときに再度例外が発生して,正常に値が得られなかった場合
- 注意事項
-
ローカル変数情報で出力するオブジェクトは,ほかのスレッドで並行して操作していることがあります。このため,このオプションを指定して出力した文字列は,実際に例外が発生したときのオブジェクトに対応する情報とは異なっているおそれがあります。
(3) クラスまたは配列型の変数の実際の型名を出力する場合の出力例
出力するローカル変数がクラスまたは配列型の場合,変数の型名と実際に代入されている値の型名が異なる場合があります。例えば,クラスの継承関係やインタフェースの実装関係によっては,異なる型名の値が変数に代入されます。
この場合に,-XX:+HitachiTrueTypeInLocalsオプションの指定によって,クラスまたは配列型の変数に実際に代入されている値の型名を追記して取得できます。
取得した文字列は,値表現の末尾に半角スペース1文字分が追記され,( )で囲まれて出力されます。このとき,出力文字列長に制限はありません。
次に,-XX:+HitachiTrueTypeInLocalsオプションが指定されている場合の出力例を示します。ここでは簡易出力フォーマットで示します。実行するプログラムは,Javaプログラムの例2です。また,この例は,-XX:HitachiCallToString=minimalオプションが指定されている場合の例です。
出力内容について説明します。
-
変数の型名はjava.lang.Objectクラスまたはjava.lang.Objectクラスの配列ですが,実際に代入されている値の型名はjava.lang.Threadクラスおよびjava.lang.Threadクラスの配列であることが出力されています。
なお,-XX:+HitachiTrueTypeInLocalsオプションは,-XX:HitachiCallToString=fullオプションとも同時に指定できます。