診断ガイド

     前  次    目次     
コンテンツの開始位置

Oracle JRockit JVM の起動が遅い

Oracle JRockit JVM の 1 つの大きな利点は、Just-In-Time (JIT) コンパイル型の JVM であることです (コードのコンパイル方式については「JRockit JVM によりコードのコンパイル方法」を参照)。つまり、JVM はメソッドを最初に実行するときに、そのメソッドをマシン コードにコンパイルします。JVM は、最初に呼び出されたときにすべてのクラスをネイティブ コードにコンパイルします。これにより、多くの新しいメソッドがコンパイルされた場合はアプリケーションの実行速度が低下します。しかし、メソッドが 2 回目に呼び出されたときには、実行が高速になります。頻繁に実行されるメソッドは後から JRockit JVM によって再コンパイルされるため、それ以降の実行ではいっそう最適化されて、アプリケーションがはるかに高速に動作するようになります。

この節では、起動の遅い JVM を見分けて、それに対処する方法について説明します。以下の内容について説明します。

 


起動が遅い場合に考えられる原因

アプリケーションの起動直後に動作が遅くなる問題には、多くの原因が考えられます。

JVM を JRockit JVM に最近切り替えた場合の特記事項

別の JVM から JRockit JVM に最近切り替えた場合に、JVM の起動が遅いと感じることがあります。特に、開発用のサードパーティの JVM から、プロダクション用の JVM として JRockit JVM に切り替えた場合はこれが顕著になります。実際には、起動が遅いように見えても、それが標準的な動作です。JRockit JVM は、長時間実行されるアプリケーションと共に使用するように設計されています。そのため、コードがコンパイルされて最適化される分だけ起動に時間がかかります。JVM の起動が遅いわけではなく、単に起動時に処理する情報が多いだけです。いったんすべてのメソッドがコンパイルされれば、JVM ははるかに高速に動作するようになります。

 


JVM の起動が遅い場合の診断

起動時にアプリケーションが大量のメソッドをコンパイルしているかどうかを確認するには、-Xverbose:codegen オプションを指定してアプリケーションを起動します。

このオプションを設定すると、名前、メモリの位置、コンパイルの持続時間、コンパイル開始からの経過時間など、コンパイルされているメソッドに関する情報が表示されます。コード リスト 26-1-Xverbose:codegen のプリントアウトの例を示します。

コード リスト 26-1 -Xverbose:codegen
[codegen] #775 1 (0x2) n jrockit/memory/AtomicInt.<init>(I)V
[codegen] #775 1 (0x2) n @0x7D62ED90-0x7D62ED9C 0.09 ms (277.99 ms)
[codegen] #776 1 (0x2) n jrockit/memory/AtomicInt.set(I)V
[codegen] #776 1 (0x2) n @0x7D62EDA0-0x7D62EDAA 0.08 ms (278.06 ms)

逆に言えば、起動時に大量のメソッドをコンパイルする必要がある場合は、そうでない場合に比べてかなりの起動時間がかかります。

いったん JIT コンパイルが完了すれば、メソッドはコンパイルされて実行にあまり時間がかからなくなります。ただし、JRockit JVM はアプリケーションの実行中に頻繁に使用されるメソッドを継続的に最適化するため、ときどき JVM の動作が遅いように見えることがあります。

 


アプリケーションの起動が遅い場合の診断

データ ファイルなど、特定のファイルを検索するアプリケーションがある場合にも、起動時間が長くなることがあります。起動が遅い原因がアプリケーションにあると思われる場合は、JRA 記録を作成し、JRockit Runtime Analyzer でアプリケーション データを分析してみます。このツールは Oracle JRockit Mission Control で含まれています。

JRockit JVM R27.1 以降を JRockit Mission Control 2.0 以降と共に実行している場合は、JRA 記録を作成および解釈するための詳細な手順が Oracle JRockit Mission Control オンライン ヘルプに記載されています。

 


nanoTime() および currentTimeMillis() によるタイミング

アプリケーションの内部でタイミングを測定するために、アプリケーションで System.nanoTime() および System.currentTimeMillis() メソッドを使用できます。アプリケーションでこれらのメソッドを使用すると、実行時にリソースを占有することになりますが、パフォーマンスへの影響はわずかです。

System.nanoTime()

このメソッドは、最も正確なシステム タイマーを使用して、単調なタイマー値を返します。戻り値はナノ秒単位ですが、タイマーの実際の時間単位は OS とハードウェアの間で異なる可能性があります。タイマー値を関連させるための通常のゼロ点はありません。したがって、有意なデータを得るには、少なくとも 2 回、時間を取得する必要があります。

nanoTime() では、オペレーティング システムごとに異なるメソッドを使用します。

タイマーの時間単位 (および、Linux では、時間値の取得に使用されるメソッド) に関する情報を取得するには、-Xverbose:timing オプションを指定して JRockit JVM を起動します。

Windows での冗長タイミング レポートの例は次のとおりです。

[INFO ][timing ] Counter timer using resolution of 1779720000Hz

System.currentTimeMillis()

このメソッドは、現在の時刻をミリ秒単位で返します。現在の時刻は 1970 年 1 月 00:00:00 UTC からの時間として定義されます。

アプリケーション起動時のミリ秒とナノ時間

JVM の起動時に System.currentTimeMillis() および System.nanoTime() の値を取得するには、コマンドライン オプション -Xverbose:starttime を使用します。starttime の冗長出力は次のようになります。

[startti] VM start time: 1152871839957 millis 171588375730523 nanos

millis 値は System.currentTimeMillis() が提供する値と同じ値、nanos 値は System.nanoTime() が提供する値と同じ値です。

 


起動が遅い場合の推奨解決策

ここでは、起動が遅い場合に取りうる解決策について説明します。

起動を高速化するチューニング

コマンド ライン オプションを使用して JVM をチューニングする方法に問題がある場合もあります。起動を高速化するために JVM をチューニングする際のヒントについては、「JVM の起動を高速化するチューニング」を参照してください。

最適化の問題の除外

まれに、最適化が原因で起動が遅くなることがあるため、その可能性を除外してから他の解決策に取りかかる必要があります。

問題の原因が最適化にあると思われる場合は、-XnoOpt 起動コマンドを指定して JVM を起動し、最適化を完全に無効にします。このコマンドを指定すると、JVM はコードの最適化を一切行わなくなります。-XnoOpt を指定して実行すると JRockit JVM の起動が速くなる場合は、最適化の問題が発生していると考えられます。Oracle サポートに問題を報告してください。

回避策として、最適化に時間がかかりすぎるメソッドを除外してみることができます。そのためには、print_threads Ctrl-Break ハンドラを使用して、スレッド ダンプを作成します (詳細については「診断コマンドの実行」を参照)。この出力から、最適化の問題の原因となっているメソッドを特定します。次に、「opt ファイル」を使用して、そのメソッドを最適化処理から削除します (詳細については「opt ファイルを作成、使用する」を参照)。

アプリケーションの問題の除外

Java アプリケーションの問題が原因で起動が遅いと判断した場合は、その問題の原因をアプリケーションの観点から調査する必要があります。多くは、不必要な同期や不十分な同期リソースのしわ寄せを受けているメソッドに問題があると考えられます。ボトルネックの原因となっているメソッドを特定し、可能であれば Java アプリケーションのコードを書き直します。

Oracle サポートへの連絡

各メソッドのコードの生成に時間がかかりすぎる原因が Oracle JRockit JVM にあると思われる場合や、「JVM の起動を高速化するチューニング」に示されているどの方法を試しても問題が解決しない場合は、Oracle サポートに連絡する必要があります。Oracle に問題を報告する方法、およびその際に提出する情報については、「Oracle サポートへのトラブル レポートの送付」を参照してください。


  ページの先頭       前  次