Java VMは、Javaアプリケーションとして実行されるJavaメソッドに対して、必要に応じて自動的にコンパイル処理(動的コンパイル)をします。
以下のオプションを指定することで、動的コンパイルが発生するたびにその発生状況ログが標準出力へ出力されます。
-XX:+PrintCompilation |
動的コンパイル発生状況のログ出力機能
どのJavaメソッドが、いつコンパイルされたかの情報を出力します。
Javaメソッドのコンパイルが、短い間に連続して発生している場合、Javaアプリケーションの実行性能に動的コンパイルが影響を与えている可能性があります。
$1 $2 $3 $4 $5 ($6 bytes) $7 |
Javaメソッドのコンパイル要求が発生した時間(ログ出力時の時間)を、Java VMが起動されてからの経過時間(ミリ秒)で示します。
コンパイル要求の数(コンパイル要求が発生したJavaメソッドの数)を通し番号で示します。
メソッドのコンパイル種別を表す5桁の文字列"%s!bn"を示します。5桁の文字は、それぞれ、動的コンパイラーが管理するメソッドの種別を表し、該当しない場合は空白が表示されます。
5桁の文字列は、動的コンパイラーの内部処理を解析するための、保守サポート向けの情報(動的コンパイラー処理ロジックを理解した高度なスキルを必要とする情報)です。
動的コンパイラーが管理するメソッドのコンパイルレベルを表す数値を示します。
コンパイル要求が発生したJavaメソッドの名前を示します。
Javaメソッドを部分的にコンパイルする要求の場合($2に「%」の表示が含まれる場合)、Javaメソッド名の後に、Javaメソッド(バイトコード)のどの部分からコンパイルの対象になっているかを示す情報「(@ 数字)」が付加されます。
コンパイル対象となったJavaメソッドの大きさ(バイトコード・サイズ)をバイト数で示します。
ネイティブメソッドの場合は、(native)が表示されます。
コンパイル対象となったJavaメソッドが、static修飾子を持つネイティブメソッドの場合は、"(static)"と出力されます。
コンパイル対象となったJavaメソッドが、ネイティブメソッドでない場合、またはstatic修飾子を持たないネイティブメソッドの場合、この位置には何も出力されません。
"made not entrant"は、これまでにコンパイラーによってつくられた機械命令のコードを無効にしたことを示します。
動的コンパイル発生状況の調査
Javaアプリケーションの実行は、Java VM起動直後はインタープリタ実行だけで行われ、次第にインタープリタ実行と動的コンパイル結果による機械命令実行との混合動作になります。また動的コンパイルにより翻訳された機械命令の内容も、Javaアプリケーションの実行が進むにつれて、次第にJavaアプリケーションの実行状況に合った翻訳結果に最適化されます。
Javaアプリケーションの実行には、以下の動的コンパイルによるオーバーヘッドや最適化状態の推移があるため、Javaアプリケーションとして安定した実行性能になるまで、プロセス起動時からある程度の時間を必要とする場合があります。
実行対象プログラムのクラスファイルを実行時に読み込むため、Javaアプリケーションとしての起動直後には、クラスファイルのロードおよび内容検査によるオーバーヘッドが発生します。
実行時に機械命令への翻訳処理をするため、そのオーバーヘッドが発生します。
機械命令への翻訳・最適化処理で必要とする情報を、Javaアプリケーション実行と同時に収集するため、Javaアプリケーション開始直後は最適化状態の推移が少なく、結果として実行性能が遅い機械命令となっている場合があります。
なお、Javaアプリケーションとして安定した実行性能になるまでに掛かる時間は、各アプリケーションによって異なります。
Javaアプリケーション実行時における動的コンパイルから受ける影響の有無は、Javaアプリケーションによる業務が開始された際に、動的コンパイルの発生頻度が高いかどうかを判断することで行います。
"動的コンパイル発生状況のログ出力機能"を使用して動的コンパイル結果情報を出力し、その結果から「動的コンパイル結果情報で、Javaメソッドのコンパイルが、短い間に連続して発生している」傾向が見て取れ、かつJavaアプリケーションとして安定した実行性能になるまでに掛かる時間との関連性が見て取れるかどうかを元に判断します。
注意
Javaアプリケーション起動時や、業務を開始してJavaアプリケーションへの入力が始まる時に、動的コンパイル処理が発生する頻度が高くなる傾向は、Javaアプリケーション実行時の一般的な傾向です。そのため、動的コンパイル発生状況の調査の結果として、「動的コンパイルの発生頻度が高い」などの傾向が見て取れる場合であっても、インタープリタ実行と機械命令による実行がバランスよく行われており、対応が不要な場合が多々あります。
Javaアプリケーションとして安定した実行性能になるまでに掛かる時間が実運用上の問題となった場合に、動的コンパイル発生状況の調査をしてください。
注意
Javaアプリケーション起動直後の性能に影響を与える処理は、動的コンパイル処理だけではありません。Javaアプリケーション自体の初期化処理や関連するアプリケーションの起動待ちなど、Javaアプリケーションの起動直後でだけ動作する動的コンパイル以外の要因についても考慮する必要があります。
注意
JavaアプリケーションがJSPで作成されている場合、アプリケーションを配備する際にJSPのプリコンパイル(javacコマンドによりJavaソースをクラスファイルへ変換する処理)が実施されていないと、Javaアプリケーション起動時にjavacコマンド実行によるオーバーヘッドが発生する場合があります。
JSPのプリコンパイル運用ができる場合は、JSPのプリコンパイルを実施することで、Javaアプリケーションとして安定した実行性能になるまでに掛かる時間が小さくなるかどうかを確認してださい。
暖気運転
Javaアプリケーションを起動した後、業務としての運用を開始する時点で安定した実行性能を得る状態にするためには、暖機運転という運用をします。
暖機運転とは、Javaアプリケーションを起動した後、実際の業務を開始する前に、業務と同様のダミーデータを使用して疑似実行させることで、事前に主なJavaメソッドを動作させ、クラスファイルのロードやJavaメソッドの動的コンパイルを完了させておくことを言います。
暖機運転により、動的コンパイルなどのオーバーヘッドを減らすことができ、また機械命令への翻訳・最適化処理もその時点で行われるようになるため、業務としての運用開始時点から安定した実行性能を得ることができるようになります。
なお暖機運転をどの程度の期間行ったら良いのかについては、Javaアプリケーションの実行性能が運用要件を満たすところまで安定しているかのかどうかが、判断の基準になります。
ただし、Javaアプリケーションを起動してから業務開始までの時間は無限にあるわけではないので、"動的コンパイル発生状況のログ出力機能"の動的コンパイル結果情報の出力結果を参考に、暖気運用に掛ける時間をある程度のところで区切る判断をする必要があります。
注意
通常、Javaアプリケーションの実行には、実行結果の表示、データの更新などの結果を伴います。暖機運転による実行結果が、Javaアプリケーションの運用自体に影響を与えないように注意する必要があります。
例えば、暖機運転用のダミーデータをそのままデータベースに登録してしまい、運用時に誤ったデータを返却するなどの問題が発生しないように注意してください。
注意
Javaアプリケーション自体の初期化処理や関連するアプリケーションの起動待ちなど、動的コンパイル以外の要因でJavaアプリケーションとして安定した実行性能になるまでに時間が掛かっている場合は、暖機運転では対処できません。