JRockit SDK ユーザーズ ガイド
![]() |
![]() |
![]() |
![]() |
コード キャッシング (またはコードの永続化) とは、生成済みのマシン コードをディスクに格納しておいて、そのコードが JVM の以降のインスタンスで必要になったときに取得できるようにするプロセスです。キャッシュされたコードは生成済みであるため、以降の起動時にコード生成にかかる時間が短くなり、通常は実行時間が短縮されます。コードの永続化をハイバネーションと混同しないようにしてください。つまり、コードだけでなくオブジェクトやヒープ全体も格納されます。
この節では、BEA JRockit のコード キャッシング機能の仕組みと実行方法について説明します。内容は以下のとおりです。
起動時間は、特に開発の際に多くの人にとって問題となります。javac
コンパイラを普通に実行する場合、起動時間の大部分は JVM でのコード生成によるものです。コード キャッシングを使用すると、起動時間、さらには実行時間を大幅に短縮できます。
「キャッシュ」とは、生成済みのコードを格納するファイル システム内のディレクトリです。キャッシュは、そのマシン上で起動した BEA JRockit のすべてのインスタンス間で共有されます。ディレクトリ自体は多種多様なファイルで構成されています。キャッシュは論理的に分割されています。各部分はコード ファイル (.code
ファイル拡張子) とインデックス ファイル (.ndx
拡張子) から成ります。各部分には番号が付けられ、コード ファイルやインデックス ファイルにも同じ番号が付きます。つまり、1.code
と 1.ndx
のようなファイルのペアになります。
コード キャッシングを有効にして BEA JRockit を起動すると、JIT で処理されたコードがキャッシュに書き込まれます。BEA JRockit は次回の実行時にこのファイルを読み込んで、必要なキャッシュ済みメソッドがあればインスタンス化します。このメソッドはコンパイルが必要なバイトコードではなく、コンパイル済みコードの状態になっています。
この節では、以下の機能を実行してコード キャッシングを使用する方法ついて説明します。
コード キャッシングを有効にするには、必要に応じて適切な引数を指定して、-XXcodecache コマンドライン オプションを使用します。次に例を示します。
-XXcodecache:[dir=directory],[readonly],[clobber]
デフォルトでは、キャッシュされたコードは「cache」というユーザごとのディレクトリに書き込まれます。デフォルトの場所は次のとおりです (Windows では実際のパス名はロケールによって異なります)。
C:¥Documents and Settings¥<username>¥Local Settings¥Application Data¥JRockit CodeCache¥
/tmp/<username>_jrockit_codecache/
別のキャッシュ ディレクトリを使用するには、-XXcodecache:dir=
コマンドを使用して新しいキャッシュ名を指定します。
-XXcodecache:dir=/path/to/myCacheDirectory
キャッシュ ディレクトリの詳細については、「コード キャッシングの仕組み」を参照してください。
デフォルトでは、コード キャッシングは読み取り/書き込みモードで動作します。つまり、BEA JRockit は新しいメソッドに遭遇すると、まずキャッシュをチェックして、キャッシュ内にそのメソッドをコンパイルしたものがあるかどうか調べます。ある場合は、それをメモリに読み込んで使用します。キャッシュからメソッドを利用できない場合は、メソッドを生成してキャッシュに格納します。
キャッシュの読み込みは行うものの、新しくコンパイルしたコードの書き込みは行わないように BEA JRockit に指示することもできます。これは、アプリケーションをプロダクション環境にデプロイしていて、動作中のキャッシュには変更を加えない場合などに便利です。readonly
を使用すると更新は行われません。readonly
を呼び出す通常のコマンドラインは次のようになります。
-XXcodecache:file=myCacheFile,readonly
表 6-1 に、dir=
および readonly
と共に使用できるその他のコード キャッシング引数を示します。
コード キャッシングを使用して起動時のパフォーマンスを向上させる最も簡単な方法は、アプリケーションを一度実行して初期キャッシュを作成してから、同じアプリケーションを再実行することです。次に例を示します。
java -XXcodecache HelloWorld
ここでキャッシュが作成されて、そのキャッシュにコンパイル済みメソッドが追加されます。
java -XXcodecache HelloWorld
ここでは以前に作成されたキャッシュを使用します。コードをコンパイルする必要がないため、実行が速くなります。
-Xverbose
:[codecache,codecache2]
オプションを使用すると、ステータス メッセージの冗長モードを設定できます。codecache
の場合は、キャッシュについての基本的な情報のほかに、保存またはロードされなかったメソッドについての情報も出力されます。冗長レベル 2 (codecache2
) の場合は、保存またはロードされるときに各メソッドに関するより詳しいメッセージが出力されます。
各コマンドラインでコード キャッシングを有効にする代わりに、環境変数 JR_CODECACHE
を設定して、BEA JRockit のすべての呼び出しでコード キャッシングを有効にすることができます。環境変数の値は -XXcodecache
の引数と同じにする必要があります。空の環境変数はどのオペレーティング システムでもサポートされていないため、デフォルトのオプションを使用する場合は、変数に値 enable
を設定します。
set JR_CODECACHE=enable
set JR_CODECACHE=ro,dir=/path/to/myCodeCache
この節では、コード キャッシングの仕組みについて説明します。以下の機能の説明があります。
コード キャッシングを有効にして Java プログラムを起動すると、BEA JRockit はキャッシュ ディレクトリにアクセスして、既存のキャッシュ ファイルを開くか、新しく空のファイルを作成します新しいメソッドが生成されると、これらのファイルに書き込みます (既存のファイルの場合は、既存の情報に新しい情報が追加されます)。最後に、停止時に新しいキャッシュ インデックスを作成して、キャッシュ ディレクトリを閉じます。致命的なエラーが発生して無効なキャッシュが作成されると、その破損したキャッシュは自動的に削除されます。
コード キャッシュはアプリケーションに固有なだけでなく、アプリケーションの用法にも固有なものです。これは、クラスの初期化順序、静的イニシャライザ、アサーションのステータス、またはアプリケーションを別の方法で実行したら変わる可能性のあるその他の条件などによって、メソッドの生成結果が異なるためです。一般に、アプリケーションの用法が大きく変わらない限り (メソッドのロード時にチェックされる)、これらの前提は有効です。大きく変わった場合は、キャッシュに格納されている一部のメソッドは無効になり、再生成する必要があります。新しく生成されたメソッドはキャッシュに追加され、キャッシュに残されていてアクセス不能になっている以前の定義は上書きされます。
コードキャッシュの機能では、キャッシュ済みコードが有効でなくなった場合、そのコードは JVM で使用できなくなります。コードがキャッシュに格納された後でクラス ファイルに変更が加えられた場合、コード キャッシング システムは、以降の実行時にその格納済みコードが取得されないようにします。インライン化やその他の最適化の結果、多くのメソッドには他のクラスやメソッドとの依存関係があり、これらの依存関係も格納しておく必要があります。取得時にメソッドが有効でなくなっている場合、その格納済みメソッドは使用されません。
変更されたコードが取得されないようにするため、BEA JRockit はクラス バイトのセキュアな checksum
(MD5) に基づいてクラスを格納します。この情報は、BEA JRockit が格納済みのメソッドを検索する際に、クラスのインデックスとして使用されます。変更されたクラスは checksum
の変化によって検出されます。そのクラスの古いバージョンに依存している格納済みメソッドは無効になり、再生成する必要があります。メソッドのロード時に依存関係のチェックが行われ、そのメソッドが無効になったクラスに依存しているかどうかが判断されます。
このバージョンの BEA JRockit には、キャッシュのクリーンアップに関する機能がありません。そのため、ときどきキャッシュを削除し、アプリケーションを再実行してキャッシュを再作成することをお勧めします。これはアプリケーションを開発中の場合にも当てはまります。その場合は、クラスを再コンパイルするとキャッシュ済みメソッドが置き換えられます。詳細については、「キャッシュのクリーンアップ」を参照してください。
アプリケーションの開発サイクルが完了し、アプリケーションの使用が安定したら、キャッシュを再生成して古くなったメソッドを削除することをお勧めします。その後で、アプリケーションを次のようにデプロイするとよいでしょう。インストール時にアプリケーションを実行してキャッシュを生成します。次に、前述の読み取り専用モードで、そのキャッシュを使用してアプリケーションを実行します。これにより、新しいメソッドがキャッシュに追加されることなく、アプリケーション キャッシュが共有されます。
生成されたキャッシュは、JVM オプションだけでなく、マシン固有の要因にも大きく左右されます。キャッシュのロード時にそのような制約が満たされない場合、そのキャッシュは無効と見なされます。キャッシュが無効になり、読み取り専用モードでコード キャッシングを実行している場合は、JVM のコード キャッシングが無効になります。読み取り/書き込みモードで実行している場合は、キャッシュの上書きが試行されます。このバージョンのコード キャッシングでは、ファイルはマシン アーキテクチャとオペレーティング システムの種類に依存しています。
コード キャッシングを有効にしている場合、BEA JRockit はコード キャッシングに固有の重大なエラーがあれば、常に回復しようとします。エラーの例としては、メモリ不足エラー、無効なコード キャッシュ形式のエラー、キャッシュの読み取りまたは書き込み中の I/O エラーなどがあります。このような場合、VM はアプリケーションを実行し続けますが、コード キャッシングは無効になり、画面上にエラー メッセージが表示されます。
一方、ロードや保存の制約が原因で個々のメソッドの格納やロードができなくなった場合は、エラーとは見なされず、その特定のメソッドの保存またはロードは行わずに、コード キャッシングが続行されます。冗長性を選択していない場合は何も報告されません。-Xverbose:codecache
を指定すると、保存またはロードされなかった特定のメソッドに関するメッセージが表示されます。
現在の BEA JRockit はキャッシュのクリーンアップを実行しません。つまり、使用されないクラスやメソッドは、それが今後も再使用されなくても、キャッシュに永続化されたままになります。これは、後で以前のバージョンのクラスを使用することにした場合に、キャッシュにクラスが残されているので便利です。ただし、このバージョンの BEA JRockit でキャッシュをクリーンアップするには、アプリケーションの開発が終了した時点で、キャッシュを再作成する必要があります。
![]() ![]() |
![]() |
![]() |