Cosminexus システム運用ガイド

[目次][用語][索引][前へ][次へ]

5.5.10 スタックトレースの調査

ここでは,スタックトレースに出力される情報のうち,日立のJavaVMで拡張された内容について説明します。

サーバやアプリケーションでトラブルが発生した場合,トラブル発生までのスタックトレースの内容を確認することで,トラブル発生の要因を調査できます。

スタックトレースは,次のどれかのタイミングで出力されます。

日立のJavaVMでは,サーバを起動するときのオプションの指定によって,スタックトレースにJavaメソッドのローカル変数についての情報を出力できます。例外発生時にJavaメソッドに定義されていたローカル変数の情報は,トラブルの要因を分析するために有効です。

なお,ここで対象にするローカル変数とは,メソッドに渡される引数およびインスタンスメソッドでの呼び出しの対象になるオブジェクト(this)のことです。ローカル変数情報には,これらのローカル変数の変数名,型名,およびローカル変数の値が出力されます。なお,型名は,基本形名,クラス名(インタフェース名を含みます)または配列形名のことです。

スタックトレースにローカル変数情報を出力するためのオプションを,次の表に示します。JavaVMの資料取得の設定については,マニュアル「Cosminexus システム構築ガイド」を参照してください。

表5-73 スタックトレースにローカル変数情報を出力するためのオプション

起動オプション スタックトレースを出力するタイミング 同時に指定できるオプション
-XX:+HitachiLocalsInThrowable サーバまたはアプリケーション内で例外が発生したとき
  • -XX:MaxJavaStackTraceDepth=<最大の深さ>
  • -XX:+HitachiLocalsSimpleFormat
  • -XX:+HitachiTrueTypeInLocals
  • -XX:HitachiCallToString=<適用範囲指定>
-XX:+HitachiLocalsInStackTrace JavaVMのスレッドダンプを出力したとき
  • -XX:MaxJavaStackTraceDepth=<最大の深さ>
  • -XX:+HitachiLocalsSimpleFormat
  • -XX:+HitachiTrueTypeInLocals

注※ ただし,発生した例外が「java.lang.StackOverflowError」または「java.lang.OutOfMemoryError」の場合,スタックトレースにローカル変数は出力されません。


次に,それぞれのオプションを指定した場合に出力される内容について,例を基に説明します。それぞれのオプションを指定した時に出力される項目の詳細については,マニュアル「Cosminexus リファレンス 定義編」を参照してください。

<この項の構成>
(1) -XX:+HitachiLocalsInThrowableオプションが指定されている場合
(2) -XX:+HitachiLocalsInStackTraceオプションが指定されている場合

(1) -XX:+HitachiLocalsInThrowableオプションが指定されている場合

java.lang.Throwable.printStackTraceメソッドで出力されるスタックトレース情報の1スタックフレーム情報ごとに,そのスタックフレームに対応するメソッド内のローカル変数情報が挿入されて出力されます。

(a) 標準の形式および簡易出力フォーマットでの出力例

ローカル変数を出力するための機能として,-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メソッドによって出力されるスタックトレース情報です。

図5-7 Javaプログラムの例1に対するローカル変数情報の出力例(-gオプションまたは-g:varsオプションを指定して作成されたclassファイルの場合)

[図データ]

出力内容について説明します。

  1. スタックトレースを出力する処理を実行したメソッドの情報が出力されます。この例では,javaプログラム1の15行目で例外が発生したときのスタックトレース情報が出力されることを示しています。
  2. ローカル変数情報として,インスタンスメソッドの呼び出しの対象になるオブジェクトについての情報が出力されます。この例の場合は,Javaプログラムの例1の3行目で作成したExample1クラスのオブジェクトのクラス名とアドレスが出力されます。
  3. ローカル変数情報として,methodメソッドの引数として指定されたローカル変数の値についての情報が出力されます。変数名の後ろの[arg*]は,何番目のメソッド引数かを示す情報です。Javaプログラムの例1の5行目でe1.methodメソッドを実行したときに指定された値が出力されます。
    なお,l1およびl2は基本型(int型およびchar型)の変数なので実際の値が出力されます。l3はjava.lang.Objectクラス型の変数なので,アドレスで出力されます。
  4. ローカル変数情報として,methodメソッド内のローカル変数のうち,メソッド引数として指定した以外のローカル変数の値についての情報が出力されます。
    なお,l4〜l6は基本型(float型,boolean型およびdouble型)の変数なので実際の値が出力されます。l7はjava.lang.Objectクラス型の変数なので,アドレスで出力されます。

次に,-XX:+HitachiLocalsSimpleFormatオプションを指定した場合の,簡易出力フォーマットでの出力例を次に示します。なお,出力内容の説明は,標準の形式と同じです。

図5-8 -XX:+HitachiLocalsSimpleFormatオプションを指定した場合の出力例

[図データ]

また,javacコマンド実行時に,-gオプションまたは-g:varsオプションを指定しなかった場合,ローカル変数情報がないため,出力内容が次のように制限されます。これらは,nativeメソッドを実行した場合も同様です。

ローカル変数情報がない場合の,Javaプログラムの例1に対する出力例を次に示します。ここでは,簡易出力フォーマットでの出力例を示します。

図5-9 ローカル変数情報がない場合の出力例(簡易出力フォーマット)

[図データ]

図5-8に比べて,次の違いがあります。

(b) クラスまたは配列型の変数を文字列として出力する場合の出力例

出力するローカル変数がクラスまたは配列型の場合,アドレスだけの値表現ではトラブルシューティングに必要な情報が取得できない場合があります。このとき,-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メソッドによって出力されるスタックトレース情報です。

図5-10 -XX:HitachiCallToString=minimalオプションを指定した場合の出力例(簡易出力フォーマット)

[図データ]

出力内容について説明します。

  1. クラス型のローカル変数のうち,文字列を出力する適用対象のクラスの型のローカル変数情報です。アドレスに続いて,文字列に変換した値が出力されます。
  2. クラス型のローカル変数のうち,文字列を出力する適用対象外のクラスの型のローカル変数情報です。アドレスだけが出力されます。

次に,-XX:HitachiCallToString=fullオプションを指定した場合の出力例を次に示します。

図5-11 -XX:HitachiCallToString=fullオプションを指定した場合の出力例(簡易出力フォーマット)

[図データ]

図5-10に比べて,次の違いがあります。

ただし,次の場合は,文字列は出力されないで,アドレスだけが出力されます。

(c) クラスまたは配列型の変数の実際の型名を出力する場合の出力例

出力するローカル変数がクラスまたは配列型の場合,変数の型名と実際に代入されている値の型名が異なる場合があります。例えば,クラスの継承関係やインタフェースの実装関係によっては,異なる型名の値が変数に代入されます。

この場合に,-XX:+HitachiTrueTypeInLocalsオプションの指定によって,クラスまたは配列型の変数に実際に代入されている値の型名を追記して取得できます。

取得した文字列は,値表現の末尾に半角スペース1文字分が追記され,( )で囲まれて出力されます。このとき,出力文字列長に制限はありません。

次に,-XX:+HitachiTrueTypeInLocalsオプションが指定されている場合の出力例を示します。ここでは簡易出力フォーマットで示します。実行するプログラムは,Javaプログラムの例2です。また,この例は,-XX:HitachiCallToString=minimalオプションが指定されている場合の例です。

図5-12 -XX:+HitachiTrueTypeInLocalsオプションを指定した場合の出力例(簡易出力フォーマット)

[図データ]

出力内容について説明します。

  1. 変数の型名はjava.lang.Objectクラスまたはjava.lang.Objectクラスの配列ですが,実際に代入されている値の型名はjava.lang.Threadクラスおよびjava.lang.Threadクラスの配列であることが出力されています。

なお,-XX:+HitachiTrueTypeInLocalsオプションは,-XX:HitachiCallToString=fullオプションとも同時に指定できます。

(2) -XX:+HitachiLocalsInStackTraceオプションが指定されている場合

スレッドダンプ内のスタックトレース情報の1スタックフレーム情報ごとに,そのスタックフレームに対応するメソッド内のローカル変数情報が挿入されて,出力されます。

出力形式および出力内容は,-XX:+HitachiLocalsInThrowableが指定されている場合に標準出力に出力される内容と同じです。

ただし,-XX:+HitachiLocalsInStackTraceオプションでは,次のオプションの指定は無効になります。

Javaプログラムの例と,それに対するスタックトレース内のローカル変数情報の出力例を示します。

Javaプログラムの例3
 
class Example3 {
    public static void main(String[] args) {
        Example3 e3 = new Example3();
        e3.method();
    }
 
    synchronized void method() {
        int l1 = 1;
        float l2 = 2.0f;
        String l3 = "local 3";
        Character l4 = new Character('X');
        Object l5 = new Thread();
        Object[] l6 = new Thread[10];
 
        <ここでスレッドダンプ出力!>
    }
}
 

出力例を次に示します。この例は,次の場合の例です。