Java VMはJavaアプリケーションとして実行されるJavaメソッドに対して必要に応じて自動的にコンパイル処理を行い、通常は極短時間でその処理を完了します。
しかし、コンパイル処理自身や同じJavaプロセス内で動作させている他の処理の障害などによりCPU資源が占有され続けてしまうと、数分を経過してもコンパイル処理が終了しない場合が考えられます。このような状態が継続すると、システム全体に対して悪影響を与える可能性が考えられます。
このため、FJVMでは、各Javaメソッドのコンパイル処理に要している時間を監視し、コンパイル処理で必要と考えられる程度の時間を経過してもコンパイル処理が終了していない場合には、Javaプロセス内の処理で何らかの問題が発生していると判断し、当該Javaプロセスを強制的に終了させる機能を「長時間コンパイル処理の検出機能」として実装しています。
本機能は、図1のオプションでコンパイル処理に対する監視時間(コンパイル処理に要する時間の上限値)を指定した場合に有効となります。ただし、オプション値として「0」を指定した場合には、本機能は有効となりません。
図1のオプションで指定された時間を超過してもコンパイル処理が終了していない場合、本機能はJavaプロセス内の処理で何からの問題が発生していると判断し、当該Javaプロセスを強制的に終了させます。
図1 長時間コンパイル処理の検出機能を有効にするオプション
-XX:CompileTimeout=<nn> |
<nn>には、本機能による異常有無の判断条件とされるコンパイル処理に要する時間の上限値(単位:秒)を指定します。デフォルト値は「0」であり、本機能は無効となっています。
なお、本機能による時間監視の最小単位は30秒であるため、その単位での時間誤差があります。
なお、本機能によってJavaプロセスを強制終了する場合、FJVMは図2のメッセージを標準出力に出力してから終了します。また、本機能によるJavaプロセスの強制終了時にはコアダンプも出力されます。
図2 長時間コンパイル処理の検出機能によるJavaプロセス強制終了時の出力メッセージ
CompilerRecovery: Information: CompilerRecovery got the VM aborted |
nnnnnnnn: コンパイラスレッドの内部識別子
method_name: 本機能によるチェックでJavaプロセス内に異常が検出された際にコンパイル対象となっていたJavaメソッドの名前
長時間コンパイル処理の検出機能に対する注意事項
何らかの要因によりJavaプロセス内のコンパイル処理へCPU資源が十分に割り当てられず、コンパイル処理自体が進んでいない場合でも、コンパイル処理開始から-XX:CompileTimeoutオプションで指定された監視時間を超過した場合には、本機能による当該Javaプロセスの強制終了となります。
このため、当該Javaプロセスを実行するシステムのCPU負荷が高い場合には、コンパイル処理に対してCPU資源が十分に割り当てられず、この結果として本機能による強制終了が発生する可能性が考えられます。
本機能による強制終了が発生した場合には、まず以下の事項を確認してください。
当該Javaプロセスを実行しているシステムのCPU資源量は十分か。
当該Javaプロセス以外の他のプロセスでCPU資源が占有されていないか。
“-XX:CompileTimeout=0”を指定した場合に本機能による強制終了が回避され、かつ、当該Javaプロセスが正常に終了する、または未負荷時に正常なアイドル状態に遷移するか。
上記事項に合致する場合は、コンパイル処理に対してCPU資源が十分に割り当てられなかった結果として発生した強制終了と考えられます。
長時間コンパイル処理の検出機能を有効にしてこの状態が発生した場合には、“-XX:CompileTimeout”オプションで指定する監視時間として、より大きな値に設定する形で調整してください。
長時間コンパイル処理の検出機能に対する監視メッセージの出力
図3のオプションを指定した場合、Javaメソッドのコンパイル処理において1分が経過すると、図4の形式で監視メッセージが出力されます。
その後は、30秒経過するごとに同じ監視メッセージが出力されます。
なお、本機能による時間監視の最小単位は30秒であるため、その単位での時間誤差があります。
図3 長時間コンパイル処理の検出機能の監視メッセージ出力を有効にするオプション
-XX:+PrintCompilerRecoveryMessage |
図4 長時間コンパイル処理の検出機能が出力する監視メッセージ
CompilerRecovery: Information: The compiler thread(0xnnnnnnnn) might not return from compiling method method_name. |
nnnnnnnn: コンパイラスレッドの内部識別子
method_name: 本機能によるチェックで検出された際にコンパイル対象となっていたJavaメソッドの名前