9.1 Oracle JVMのJust-In-Time(JIT)コンパイラ

この項では、Oracle Database 11gリリース1(11.1)以降で導入されているJust-In-Time(JIT)コンパイラについて説明します。この項の内容は次のとおりです。

ノート:

以前のバージョンのOracle Databaseで使用されていたコンパイラが、JITコンパイラに切り替えられています。

9.1.1 Oracle JVMのJITの概要

Oracle JVM用のJITコンパイラでは、外部のメカニズムを使用せずにコードの無効化、再コンパイルおよび格納を管理するため、実行速度が上がります。

このコンパイラは、動的に収集されたプロファイル・データに基づき、ネイティブのマシン・コードをコンパイルするためにJavaメソッドを透過的に選択し、Javaセッションの実行でこれらのメソッドを動的に使用できるようにします。さらに、Oracle JVMのクラスの解決モデルを利用して、データベースのコール、セッションまたはインスタンス間でコンパイル済Javaメソッドをオプションで存続できるようにします。Javaコードのセマンティクスが変わらないと判断される場合、このように存続させることで、セッションまたはインスタンス間の不要な再コンパイルのオーバーヘッドが回避されます。

JITコンパイラは、java_jit_enabledと呼ばれるブール値の新しい初期化パラメータで制御します。java_jit_enabledパラメータの値をtrueに指定して使用頻度の高いJavaメソッドを実行する場合、そのJavaメソッドはJITコンパイラによってネイティブ・コードに自動的にコンパイルされ、インスタンスのすべてのセッションで使用できるようになります。また、java_jit_enabledパラメータをtrueに設定すると、JITコンパイルが中止し、すでにコンパイルしたメソッドを解析に戻します。VMは、包含Javaクラスの次の再解決のように、必要に応じてJavaメソッドのネイティブ・コードを自動的に再コンパイルします。

ノート:

Linuxの場合、Oracle JVM JITではPOSIX共有メモリーが使用され、これには/dev/shmディレクトリへのアクセスが必要です。/dev/shmディレクトリのタイプはtmpfsである必要があり、次のようにしてこのディレクトリをマウントする必要があります。

  • rwおよびexecute権限が設定されている

  • noexecまたはnosuidが設定されていない

適切なマウント・オプションを使用しない場合、データベースのインストール時に次の障害が発生する可能性があります。

ORA-29516: Aurora assertion failure: Assertion failure at joez.c:
Bulk load of method java/lang/Object.<init> failed; insufficient shm-object space

JITコンパイラは、インスタンスの単一のバックグラウンド・プロセスでMMONワーカー・プロセスとして実行されます。そのため、JITコンパイラが実行中で、メソッドをアクティブにコンパイルしている間には、このCPUとメモリー・リソースを消費するバックグラウンド・プロセスが、アクティブなユーザーJavaセッションと同じになることがあります。

9.1.2 JITコンパイルの利点

次に、以前のバージョンのOracleデータベースで使用されるコンパイル方法よりも優れたJITコンパイルの利点を示します。

  • JITコンパイルは、透過的に動作します。

  • JITコンパイルは、Javaクラスのパフォーマンスを高速化します。

  • Javaコードのセマンティクスが変わらないと判断される場合、JITが格納したコンパイル済コードにより、セッションまたはインスタンス間のJavaプログラムの再コンパイルが回避されます。

  • JITコンパイルは、Cコンパイラが不要です。

  • JITコンパイルは、一部の配列境界チェックを行いません。

  • JITコンパイルは、ブロック内の共通副次式を除去します。

  • JITコンパイルは、空のメソッドを除去します。

  • JITコンパイルは、ローカル変数の割当てを登録するための領域を定義します。

  • JITコンパイルは、フロー分析の必要がありません。

  • JITコンパイルは、インライン・コードを制限します。

9.1.3 Oracle Database 11gで導入されたメソッド

11g リリース1 (11.1)以降では、DBMS_JAVAパッケージが次の新しいpublicメソッドによって拡張され、同期メソッドのコンパイルを制御し、解析したメソッドの実行に戻すためのJavaエントリ・ポイントが提供されます。

set_native_compiler_option

このプロシージャは、ネイティブ・コンパイラのオプションを現行スキーマの指定の値に設定します。optionNameで指定したオプションで値の重複が許可されない場合、この値は無視されます。

PROCEDURE set_native_compiler_option(optionName VARCHAR2,
value VARCHAR2);

unset_native_compiler_option

このプロシージャは、現行スキーマについて、ネイティブ・コンパイラのオプション/値のペアの設定を解除します。optionNameで指定したオプションで値の重複が許可されない場合、この値は無視されます。

PROCEDURE unset_native_compiler_option(optionName VARCHAR2,
value VARCHAR2);

compile_class

このファンクションは、現行スキーマのclassnameで特定されるクラスで定義されたすべてのメソッドをコンパイルします。コンパイルが成功したメソッドの数を戻します。クラスが存在しない場合、ORA-29532 (捕捉されないJava例外)が発生します。

FUNCTION compile_class(classname VARCHAR2) return NUMBER;

uncompile_class

このファンクションは、現行スキーマのclassnameで特定されるクラスで定義されたすべてのメソッドをアンコンパイルします。アンコンパイルが成功したメソッドの数を戻します。引数permanentpの値がゼロ以外の場合、これらのメソッドを動的アンコンパイルが永久に可能であるものとしてマークします。それ以外は、今後の動的な再コンパイルの対象となります。クラスが存在しない場合、ORA-29532 (捕捉されないJava例外)が発生します。

FUNCTION uncompile_class(classname VARCHAR2,
permanentp NUMBER default 0) return NUMBER;

compile_method

このファンクションは、現行スキーマのclassnameで特定されるクラスで定義されたnameおよびJava typeシグネチャで指定したメソッドをコンパイルします。コンパイルが成功したメソッドの数を戻します。クラスが存在しない場合、ORA-29532 (捕捉されないJava例外)が発生します。

FUNCTION compile_method(classname  VARCHAR2,
methodname VARCHAR2,
methodsig  VARCHAR2) return NUMBER;

uncompile_method

このファンクションは、現行スキーマのclassnameで特定されるクラスで定義されたnameおよびJava typeシグネチャで指定したメソッドをアンコンパイルします。アンコンパイルが成功したメソッドの数を戻します。引数permanentpの値がゼロ以外の場合、メソッドを動的アンコンパイルが永久に可能であるものとしてマークします。それ以外は、今後の動的な再コンパイルの対象となります。クラスが存在しない場合、ORA-29532 (捕捉されないJava例外)が発生します。

FUNCTION uncompile_method(classname  VARCHAR2,
methodname VARCHAR2,
methodsig  VARCHAR2,
permanentp NUMBER default 0) return NUMBER;