Interstage Application Server トラブルシューティング集
目次 索引 前ページ次ページ

第18章 Java実行環境運用時の異常

18.3 FJVMのトラブルシューティング機能

 FJVMでは富士通独自技術により、Java VM制御に関するトラブルシューティング機能として以下の機能を実装しています。

■Java VM異常終了時のログ出力機能の強化

 FJVMでは「Java VM異常終了時のログ出力機能」の強化を行なっています。
ログ情報の見方については、“FJVMログの見方”を参照してください。

■Java VM終了時における状態情報のメッセージ出力機能

 Javaアプリケーションを実行させた際、特別なメッセージ出力などがないままJavaプロセスが予想外の状態で終了してしまった場合、その原因の一つとして以下の原因が考えられます。

 『Javaアプリケーションが「java.lang.Runtime.exit()」を予想外の箇所で実行した』または
 『Javaアプリケーションが「java.lang.Runtime.halt()」を予想外の箇所で実行した』または
 『Javaアプリケーションが「java.lang.System.exit()」を予想外の箇所で実行した』

 以降、「java.lang.Runtime.exit()」を例にして説明します。

 Javaアプリケーションが明示的にJavaプロセスを「java.lang.Runtime.exit()」実行により終了させた場合、Java VM側から見ると正常な仕様動作であるため,Java VMとして特別なメッセージ出力などは行いません。そのため、ソースなどがなく内部処理動作の詳細が不明なJavaアプリケーションを実行させた際に上記現象が発生した場合には、ソース確認などが行えないため、「java.lang.Runtime.exit()」実行の有無を確認することができません。

 そのためFJVMでは、「java.lang.Runtime.exit()」実行の有無が確認できる様に、java.lang.Runtime.exit()によるJavaプロセス終了時に当該処理を要求したJavaスレッドのJavaスタックトレースを出力する機能を「Java VM終了時における状態情報のメッセージ出力機能」として実装しています。

 本機能は以下のオプションを指定した場合に有効となり、java.lang.Runtime.exit()を実行したJavaスレッドのJavaスタックトレース情報などが標準出力へ出力されます。

-XX:+VMTerminatedMessage

【Java VM終了時における状態情報のメッセージ出力機能による出力例】

  --------------------------------------------------------------------------------
    Thread dump at JVM_Halt(status code=1234):
    "main" prio=5 tid=0x00286240 nid=0x394 runnable [6f000..6fc10]
                            at java.lang.Shutdown.halt(Native Method)
                            at java.lang.Shutdown.exit(Shutdown.java:211)
          - locked <0x16b66d48> (a java.lang.Class)
                            at java.lang.Runtime.exit(Runtime.java:90)
                            at java.lang.System.exit(System.java:715)
                            at JVM_Halt.main(JVM_Halt.java:5)
    
    #### JavaVM terminated: Java HotSpot(TM) Server VM (1.3.1_FUJITSU_MODIFIED-B** mixed mode),
    [pid=540] TimeMillis=1093910278155 Time=Tue Apr 19 09:30:12 2005
  --------------------------------------------------------------------------------

 上記例の場合、JVM_Halt.mainからjava.lang.Runtime.exit()が実行されたことになります。

 上記オプションを指定した状態でJavaスタックトレースの情報が出力されない場合(「#### JavaVM terminated: …」から始まるメッセージ出力だけの場合)は、java.lang.Runtime.exit()が使用されず、Javaアプリケーション側の制御論理として終了したと考えられます。
 また上記オプションを指定してもJavaスタックトレースなどの情報が何も出力されない場合は、JNIモジュールの中からexit()関数呼出しによりJavaプロセスが終了したなど、別原因によるJavaプロセスの終了だと考えられます。

補足

 上記オプションを指定した場合、標準出力への出力結果はFJVMのログ情報としてファイルへも格納されます。
 ファイル名や格納先はJava VM異常終了時のログ出力時と同じです。詳細は、“FJVMログの見方”を参照してください。

■スタックオーバーフロー検出時のメッセージ出力機能

 Java VMがセグメンテーション・フォールト発生により異常終了した場合、プログラム的な問題の他に、当該Javaアプリケーション実行時のスレッドに対するスタックサイズ不足による異常終了、すなわちスタックオーバーフローが原因による異常終了の場合も考えられます。
 スタックオーバーフローが原因の場合には,例外を検出したスレッドに対するスタックサイズを大きくすることで問題が解決する可能性があります。
 そのためFJVMでは、スタックオーバーフローと考えられるセグメンテーション・フォールトの場合には、その旨をログとして出力する機能を「スタックオーバーフロー検出時のメッセージ出力機能」として実装しています。
 ログ情報の見方については、“FJVMログの見方”を参照してください。

本機能の対象となるスレッド

 本機能でスタックオーバーフロー検出の対象となるスレッドは、Javaアプリケーションから起動されたスレッドです。その他のJNI処理モジュールなどから起動されたスレッドは本機能の対象とはなりません。
 なお、mainメソッドが実行されるスレッドはJavaアプリケーションから起動されたスレッドではないため、本機能による検出対象とはなりません。
 ただし、Windows版FJVMおよびLinux版FJVMの場合は、mainメソッドが実行されるスレッドやJNI処理モジュールなどから起動されたスレッドの場合であっても、そのスレッドで実行されるJavaアプリケーションの中から呼び出されたネイティブメソッド内で直接発生したスタックオーバーフローについては、本機能による検出対象となります。

Windows版FJVMに対する注意事項

 Windows版FJVMの場合、スタックオーバーフローが発生してもFJVM側の処理へWindows OS側から制御が渡らないことがあります。その場合はFJVMログが出力されません。
 Windows OSの制御処理がWindowsのワトソン博士へ直接例外制御を渡した場合には、ワトソン博士が出力するログファイル「drwtsn32.log」の出力結果を確認してください。
 なお、スタックオーバーフロー発生時のスタック残量が少ない場合には、スタックオーバーフロー発生例外に対する制御が上記のどちらにも渡らず,そのままアプリケーションが終了してしまうことがあります。その場合は、スタックオーバーフロー発生を検出することができません。

Solaris OE版FJVM 1.3.1に対する注意事項

 Solaris OE版FJVM 1.3.1の場合、本機能を有効とするためには、新たにJava VMが管理するスレッドをLWPに結びつけて結合ユーザスレッドにする必要があります。結合ユーザスレッドを使用すると従来よりもシステム資源を多く使用する様になるため、本機能を有効としたSolaris OE版FJVM 1.3.1を使用して多量のスレッドを用いる様な既存処理をシステム移行/実行する場合には、システム性能やシステム資源量などに影響がでる可能性も考えられます。
 そのためSolaris OE版FJVM 1.3.1では、本機能を標準では有効にしていません。Solaris OE版FJVM 1.3.1を使用した既存処理において本機能を使用する場合には、システム性能やシステム資源量などの検証を行ってから使用する様にしてください(特に多量のスレッドを用いる様なJavaアプリケーションの場合)。
 なおSolaris OE版FJVM 1.3.1でスタックオーバーフロー検出時のメッセージ出力機能を有効とする場合には、以下のオプションを指定します。

-XX:+DetectStackOverFlow

■コンパイラ異常発生時の自動リカバリ機能

 Java VMはJavaアプリケーションとして実行されるJavaメソッドに対して必要に応じて自動的にコンパイル処理を行いますが、コンパイル処理を行っている際にコンパイラ内で何らかの異常が発生すると、当該Javaメソッドに対するコンパイル処理だけでなくJava VMとしての動作も異常状態として停止させてしまう場合があります。
 FJVMでは、コンパイラ内で何らかの異常が発生した場合に自動的にリカバリ処理を行い、Java VMとしての動作を継続させる機能を「コンパイラ異常発生時の自動リカバリ機能」として実装しています。

補足

コンパイラ内で何らかの異常が発生した際にコンパイル対象となっていたJavaメソッドは、以降、コンパイル処理の対象とはなりません。当該Javaメソッドについてはコンパイルされず、インタプリタモードのままJavaアプリケーションとしての実行が継続されます。

 なお本機能はFJVMの内部処理として動作する機能であるため、コンパイラ内で何らかの異常が発生してもリカバリ処理が正常に行われた場合には、外部に対する通知などは何も行いません。リカバリ処理が正常に行われた場合でもコンパイラ内で何らかの異常が発生したことを情報として受け取る場合には、以下のオプションを指定してください。

-XX:+PrintCompilerRecoveryMessage

 上記オプションを指定した場合、リカバリ処理の情報が以下のフォーマットで標準出力に出力されます。

CompilerRecovery: Information: The compilation order was canceled in compiling method method_name.
Reason for the cancellation: reason [code:c, addr:xxxxxxxx]

■長時間コンパイル処理の検出機能

 Java VMはJavaアプリケーションとして実行されるJavaメソッドに対して必要に応じて自動的にコンパイル処理を行い、通常は極短時間でその処理を完了します。
 しかし、コンパイル処理自身や同じJavaプロセス内で動作させている他の処理の障害などによりCPU資源が占有され続けてしまうと、数分を経過してもコンパイル処理が終了しない場合が考えられます。そのような状態が継続すると、システム全体に対して悪影響を与える可能性が十分に考えられます。
 そのため、FJVMでは、各Javaメソッドのコンパイル処理に要している時間を監視し、コンパイル処理で必要と考えられる程度の時間を経過してもコンパイル処理が終了していない場合には、Javaプロセス内の処理で何らかの問題が発生していると判断し、当該Javaプロセスを強制的に終了させる機能を「長時間コンパイル処理の検出機能」として実装しています。

 本機能によるコンパイル処理に対する時間監視処理で異常が検出されてJavaプロセスを強制終了する場合、FJVMは以下のメッセージを標準出力に出力してから終了します。また本機能によるJavaプロセスの強制終了時にはコアダンプも出力されます。

CompilerRecovery: Information: CompilerRecovery got the VM aborted
because the compiler thread(nnnnnnnn) has not completed.
(compiling method: method_name)

 nnnnnnnn:コンパイラスレッドの内部識別子
 method_name:本機能によるチェックでJavaプロセス内に異常が検出された際にコンパイル対象となっていたJavaメソッドの名前

 本機能によるコンパイル処理に対する時間監視処理では、以下のオプションで指定された時間を超過してもコンパイル処理が終了していない場合に、Javaプロセス内の処理で何からの問題が発生していると判断します。

-XX:CompileTimeout=nn

 nn:本機能による異常有無の判断条件とされるコンパイル処理に要する時間の上限値(単位:秒)。
 この値のデフォルト値は5分(注1)です。

 なお上記オプション値として「0」を指定した場合は、本機能による監視時間超過に因る当該Javaプロセスの強制終了は行われません。

補足

 以下のオプションを指定した場合、Javaメソッドのコンパイル処理において1分(注1)が経過すると監視メッセージが出力されます。その後は30秒経過するごとに同じ監視メッセージが出力されます。

-XX:+PrintCompilerRecoveryMessage

 監視メッセージは、以下のフォーマットで標準出力に出力されます。

CompilerRecovery: Information: The compiler thread(0xnnnnnnnn) might not return from compiling
method method_name.

 nnnnnnnn:コンパイラスレッドの内部識別子
 method_name:本機能によるチェックで検出された際にコンパイル対象となっていたJavaメソッドの名前

注1

 本機能による時間監視の最小単位は30秒であるため、その単位での時間誤差があります。

注2

 何らかの要因によりJavaプロセス内のコンパイル処理へCPU資源が十分に割り当てられず、コンパイル処理自体が進んでいない場合でも、コンパイル処理開始から-XX:CompileTimeoutオプションで指定された監視時間を超過した場合には、本機能に因る当該Javaプロセスの強制終了となります。
 そのため、当該Javaプロセスを実行するシステムのCPU負荷が高い場合には、コンパイル処理に対してCPU資源が十分に割り当てられず、その結果として本機能に因る強制終了が発生する可能性が考えられます。
 本機能による強制終了が発生した場合には、まず以下の事項を確認してください。
 上記事項に合致する場合は、コンパイル処理に対してCPU資源が十分に割り当てられなかった結果として発生した強制終了と考えられます。この状態が発生した場合には、-XX:CompileTimeoutオプションで指定する監視時間を5分以上(300以上)に設定する形で調整してください。

目次 索引 前ページ次ページ

Copyright 2006 FUJITSU LIMITED