Jump to content 日本-日本語
日本HPホーム 製品とサービス サポートとドライバ ソリューション ご購入方法
≫  お問い合わせ
日本HPホーム
製品とサービス  >  ソフトウェアとOS  >  HP- UX Developer Edge

メモリ・リーク解析とHotSpot JVM

HP-UX 11i v3 Update 3
ミッションクリティカル環境での仮想化機能を強化
UNIXの教科書 応用編
2日目:ファイルの検索
HAクラスタの教科書
第2日目:ネットワークを設定する
特集:第4世代の仮想化ソフトウェアIntegrity VM4.0の魅力を徹底解剖
コンテンツに進む
メモリ・リーク解析とHotSpot JVM
メモリ・リーク解析とHotSpot JVM
HPjmeterによるメモリ・リーク解析
HotSpot JVMの特性を知る

HotSpot JVMの特性を知る


後半では、Javaパフォーマンス・チューニングの仕上げとして、HotSpot JVMに固有のふるまいを学びます。HotSpot JVMではパフォーマンスを改善できないケースを明らかにし、その対象方法を説明します。

アプリケーションのチューニングの効果を比較するためにしばしば作成されるのが、簡単なベンチマーク・プログラムです。しかし、HotSpotベースのJVMでは、ベンチマークの設計のまずさが誤解を生む原因となりかねません。たとえば、ベンチマークによっては、旧型のJIT(Just-In-Time)コンパイラを備えたClassic JVMの方が高速になることもあるのです。

まずは、以下のベンチマークを見てください。

public class SimpleBenchmark {
   public static void main(String[] argv) {
      int value=0;

      // Record the start time.
      long start= System.currentTimeMillis();

      // Repeatedly executes feature to measure performance.
      for (int i=0; i<100000000; i++) {
         // Replace line with your favorite computation.
         value +=i;
      }

      // Record the finish time.
      long finish= System.currentTimeMillis();

      // Now report how long test ran.
      System.out.print ("Time spent = " +
      Long.toString(finish - start) + " ms\n");
   }
}

ご覧のとおり、ループを10億回繰り返し、その経過時間を計るという簡単なベンチマークです。このプログラムをコンパイルし、デフォルトのHotSport JVMで実行すると、以下のような結果が得られます。

$ /opt/java1.3/bin/java SimpleBenchmark
Time spent = 24168 ms

一方、JVMの起動オプションに-classicを指定し、Classic JVMで実行してみます。

$ /opt/java1.3/bin/java -classic SimpleBenchmark
Time spent = 911 ms

このように、HotSpot JVMはClassic JVMよりも25倍も遅いという結果が得られます。

ここで、JITコンパイルを一切行わず、すべてをインタプリタ実行するとどのような結果が得られるか、試してみましょう。HP JVMでは、-Xintオプションを指定することで、純粋なインタプリタとしてJVMを動作させることができます。その結果は以下の通りです。

$ /opt/java1.3/bin/java -Xint SimpleBenchmark
Time spent = 24100 ms

このように、上述したHotSpot JVMによる結果は、インタプリタ実行時の結果とほぼ同じであることがわかります。


HotSpot JVMとClassic JVM


では、なぜこのような違いが表れるのでしょうか。その理由を探るために、HotSpot JVMとClassic JVMの差を比較してみます。

Classic JVM

JIT(Just-In-Time)コンパイラを搭載する。実行されるすべてのコードをコンパイルする

HotSpot JVM

HotSpotコンパイラを搭載する。アプリケーションにおいてもっとも実行頻度の高い部分のみコンパイルする

一般的なプログラムでは、コードの20%の部分に実行時間の80%が費やされるという、いわゆる80/20の法則が当てはまります。HotSpot JVMは、この80/20の法則に基づいて設計されています。つまり、同JVMでは最初はアプリケーションをインタプリタ・モードで実行し、コードの実行頻度の解析を行います。これにより、「HotSpot」すなわち実行頻度の高い部分を特定したならば、その部分についてのみバイナリ・コードへのコンパイルやインライン展開などの最適化を実施します。これに対し、Classic JVMでは、実行されるすべてのコードをコンパイルするため、コンパイル時間がオーバーヘッドとなります。

本来であれば、HotSpot JVMの方がClassic JVMよりも優れたパフォーマンスを実現できるはずです。しかし、上述したベンチマークの例では、ループを含むメソッドが1回しか呼び出されないため、インタプリタ・モードのままループを実行してしまうのです。

こうした場合は、HP JVMの起動オプションとして-XX:+UseOnStackReplacementを指定し、On Stack Replacement機能を有効にします*。同機能を利用すると、メソッド呼び出しの最中でも、インタプリタ・モードからコンパイルされたバイナリ・コードの実行に切り替えられるようになります。

*この機能を有効にするためには、現時点ではパッチ (HPUX11.0:PHKL_24943, HP-UX11i PHKL_24751 )が必要です。また同時に、コンパイラのセーフポイント機能も有効にする必要があります(-XX:+UseCompilerSafepoints)。詳細はSDK 1.3.1.02 以降のリリースノートを参照してください。

このオプションを指定して先のベンチマークを実行すると、以下のようになります。

$/opt/java1.3/bin/java
  -XX:+UseCompilerSafepoints
  -XX:+UseOnStackReplacement SimpleBenchmark
Time spent = 42 ms

このように、Classic JVMより優れた結果が得られることがわかります。


HotSpot最適化にかかる時間


上記のベンチマークのように、比較的短い時間で終了するものは「マイクロ・ベンチマーク」と呼ばれます。しかし上述したとおり、HotSpot JVMでは最適化をはじめる前にインタプリタ・モードでコードを実行し、HotSpotの分析に時間を費やします。そのため、マイクロ・ベンチマークでは、HotSpot JVMによる最適化の効果をほとんど得ることができません。

HotSpot JVMにおいて、こうしたマイクロ・ベンチマークで十分なパフォーマンスを得るには、ベンチマーク部分をメソッドとして切り出し、それを繰り返し呼び出すようにコードを修正します。以下は、上述のベンチマークを修正した例です。

public class HotSpotBenchmark {
   public static void runTest() {
      int value=0;

      // Repeatedly executes feature to measure performance.
      for (int i=0; i<100000000; i++) {

         // Replace line with your favorite computation.
         value +=i;
      }
   }

   public static void main(String[] argv) {
      // Run benchmark multiple times. This will allow us to
      // see when HotSpot begins executing compiled code.

      for (int i = 0; i < 8; i++) {

      // Record the start time.
      long start= System.currentTimeMillis();

      // Run benchmark test.
      runTest();

      // Record the finish time.
      long finish= System.currentTimeMillis();

      // Now report how long test ran.
      System.out.print ("Time spent = " +
         Long.toString(finish - start) + " ms\n");

      }
   }
}

このプログラムをHotSpot JVMで実行すると、以下のような結果が得られます。

$ /opt/java1.3/bin/java HotSpotBenchmark
Time spent = 23372 ms
Time spent = 23400 ms
Time spent = 23372 ms
Time spent = 11 ms
Time spent = 11 ms
Time spent = 11 ms

ここで、ベンチマーク部分のメソッドはインタプリタ・モードのままで3回実行されていることに注目してください。一般には、HotSpot JVMが最適化を終えるまでには1〜2分を要します。その最適化の結果、HotSpot JVMではClassic JVMの80倍の高速化を達成していることが分かります。

パフォーマンス・チューニングを目的としてベンチマークを作成する際には、それがアプリケーション全体のアーキテクチャを反映できているかを見直してください。HotSpot JVMの効果を高めるには、そのベンチマークが十分に長時間実行され、「HotSpot」部分が繰り返し呼び出されなくてはならないのです。

トップへ 戻る    


その他のコラム(連載)もお読み下さい

UNIXの教科書 応用編 〜はじめよう! WindowsとLinuxからのステップアップ〜
第2日目:ファイルの検索
第1日目:grepコマンドと正規表現
HAクラスタの教科書 〜簡単!ライバルに差をつけるHP Serviceguard構築〜
第2日目:ネットワークを設定する
第1日目:ハードウェア構成を知る
 
 
 
 
知っておくべきセキュリティ対策 -HP-UXのセキュリティを極める- 全7回
UNIXの教科書〜はじめよう! WindowsとLinuxからのステップアップ〜 全7回
SMHでらくらくHP-UXシステム管理 全9回
Integrity VMでやさしく学ぶサーバ仮想化 全10回
はじめてのHP-UX 全12回
HP-UX 11iカーネル・チューニング技法 全2回
DBシステム開発者のためのサーバプラットフォーム移行ガイド 全5回
Javaパフォーマンス・チューニング 全6回
 

本ページの内容は執筆時の情報に基づいており、異なる場合があります。
印刷用画面へ
プライバシー 本サイト利用時の合意事項 ウェブマスターに連絡
© 2008 Hewlett-Packard Development Company, L.P.