ヘッダーをスキップ
Oracle® Database Java開発者ガイド
11gリリース2 (11.2)
B56280-05
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

9 Oracle Database Javaアプリケーションのパフォーマンス

Javaアプリケーションのパフォーマンスは、次の方法で向上させることができます。

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

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


注意:

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

Oracle JVM JITの概要

Oracle 11gリリース1(11.1)以降には、Oracle JVM環境用のJust-In-Time(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メソッドのネイティブ・コードを自動的に再コンパイルします。

JITコンパイラは、インスタンスの1つのバックグラウンド・プロセスでMMONスレーブとして実行されます。そのため、JITコンパイラが実行中で、メソッドをアクティブにコンパイルしている際には、このCPUとメモリー・リソースを消費するバックグラウンド・プロセスが、アクティブなユーザーJavaセッションと平行して表示されます。

JITコンパイルの利点

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

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

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

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

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

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

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

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

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

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

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

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;

Javaのメモリー使用量

標準およびカスタムのデータベース・インストール・プロセスでは、開発時に標準的なJava使用のために構成されているデータベースが提供されます。ただし、Javaの実行時の使用量は、デプロイされたアプリケーションのシステム・リソースの使用率によって決まります。開発時に使用するリソース率は、実行するアクティビティによって大きく異なる場合があります。次の各項では、メモリーの構成方法、システム・グローバル領域(SGA)メモリーの使用量を調べる方法、およびJavaが使用するメモリーの問題を示すエラーについて説明します。

メモリー初期化パラメータの構成

次のデータベース初期化パラメータを変更して、アプリケーションに必要なメモリー使用量がより正確に反映されるようにメモリー使用量をチューニングできます。

  • SHARED_POOL_SIZE

    共有プール・メモリーはJVM内のクラス・ローダーによって使用されます。クラス・ローダーは、クラスをロードするたびに平均約8KBのメモリーを使用します。共有プール・メモリーは、データベースにクラスをロードして解決するときに使用されます。また、データベース内でソースをコンパイルする場合やデータベースでJavaリソース・オブジェクトを使用する場合にも使用されます。

    SHARED_POOL_SIZEで指定したメモリーは、loadjavaツールの使用時に一時的に消費されます。データベース初期化プロセスでは、約8,000クラスのJavaバイナリをロードして解決するため、SHARED_POOL_SIZEを96MBに設定する必要があります。コール仕様を作成するとき、および実行時に動的にロードされたJavaクラスをシステムで追跡するときも、SHARED_POOL_SIZEリソースが消費されます。

  • JAVA_POOL_SIZE

    Oracle JVMメモリー・マネージャでは、主にJavaメソッドとクラス定義のメモリー内表現と、共有サーバー・モードでコール終了時にセッション領域に移行した静的Javaの状態のためにJAVA_POOL_SIZEを使用します。前者の場合は、メモリー・コストをすべてのJavaユーザー間で分担します。後者の場合は、各セッションの静的変数で保持する実際の状態数に基づいて、JAVA_POOL_SIZEの値が変わります。ただし、最小値を50MBにすることをお薦めします。

  • JAVA_SOFT_SESSIONSPACE_LIMIT

    このパラメータを使用すると、1つのセッションにおけるJavaのメモリー使用量に弱い制限を指定でき、Javaのメモリー制限を増やす必要がある場合は警告を表示できます。メモリーが割り当てられるたびに、割り当てられたメモリーの合計量がこの制限に対してチェックされます。

    ユーザーのセッション中にJavaの状態がこのサイズを超えると、Oracle JVMが警告を生成し、トレース・ファイルに書き込みます。この警告は情報用のメッセージでアプリケーションに影響を与えませんが、デプロイするクラスのメモリー要件、特にセッション領域の使用量に関する要件を把握して管理する必要があります。


    注意:

    このパラメータは共有サーバー環境にのみ適用できます。

  • JAVA_MAX_SESSIONSPACE_SIZE

    ユーザーがコール可能でサーバー上で実行されているJavaプログラムを、メモリー使用量を制限しない方法で実行できる場合は、このパラメータを使用して、使用可能なセッション領域に対して強い制限を設定できます。デフォルトは4GBです。この上限は、通常到達することのない高い値に設定します。

    ユーザーのセッション中のJavaの状態がこのサイズを超えそうになると、メモリー不足障害が発生します。


    注意:

    このパラメータは共有サーバー環境にのみ適用できます。

データベース・テンプレート内のプール・サイズの初期化

データベースのインストール・テンプレートのJAVA_POOL_SIZEおよびSHARED_POOL_SIZEに対して、デフォルト値を設定できます。

図9-1に示すように、これらの値は、Database Configuration Assistantの「メモリー」セクションで変更できます。

図9-1 Oracle JVMのメモリー・パラメータの構成

図9-1の説明は次にあります。
「図9-1 Oracle JVMのメモリー・パラメータの構成」の説明

Javaプール・メモリー

Javaプール・メモリーはSGAのサブセットで、ページワイズに調整する必要があるメモリー用にJavaによって排他的に使用されます。大部分はこのように使用されますが、Javaクラスの共有定義にメモリーのすべてが使用されるわけではありません。Javaプール・メモリーの他の使用方法は、Oracle Databaseサーバーの実行モードによって異なります。

専用サーバーで使用されるJavaプール・メモリー

次に、専用サーバーで使用されるJavaプール・メモリーの構成を示します。

  • 使用される各Javaクラスのほとんどの共有部分。

    これには、コード・ベクトルやメソッドなどの読取り専用メモリーが含まれます。合計すると、各クラスについて約4KBから8KBになります。

  • 各セッションのセッション当たりのJavaの状態は使用されません。

    専用サーバーの場合、これはSGAではなく、プログラム・グローバル領域(PGA)内のユーザー・グローバル領域(UGA)に格納されます。

専用サーバーでは、必要なJavaプール・メモリー合計は実行するアプリケーションによって異なり、通常、10から50MB程度になります。

共有サーバーで使用されるJavaプール・メモリー

次に、共有サーバーで使用されるJavaプール・メモリーの構成を示します。

  • 使用される各Javaクラスのほとんどの共有部分。

    これには、ベクトルやメソッドなどの読取り専用メモリーが含まれます。合計すると、通常、各クラスについて約4KBから8KBになります。

  • セッション・メモリーごとに使用されるUGAの一部は、Javaプール・メモリーから割り当てられます。特に、データベースのコール間で使用中になっているオブジェクトのメモリーは、常にJavaプールから割り当てられます。

    Javaプール・メモリーのサイズは制限されているため、アプリケーションで必要なメモリー量を見積り、アプリケーションで作成する同時実行セッション数を乗じて、必要なJavaプール・メモリーの総量を計算する必要があります。各UGAは必要に応じて拡大または縮小できます。ただし、UGA全体が一定のJavaプール領域に収まるようにしてください。

共有サーバーでは、Javaプールは非常に大きくなる場合があります。Java集中型のマルチ・ユーザー・アプリケーションでは、100MB以上が必要になる場合があります。


注意:

クライアントでコードをコンパイルしてからサーバーにロードするのではなく、サーバー上でコードをコンパイルする場合は、JAVA_POOL_SIZEをデフォルトの20MBより大きいサイズに設定する必要がある場合があります。

Javaプール・メモリー使用量の表示

V$SGASTAT表を表示すると、Javaプール・メモリーの使用量を調べることができます。この表の行には、プール、名前およびバイト数が表示されます。特に、最後の2行にはJavaプール・メモリーの使用量と空き容量が表示されます。この2行の数字の合計値は、データベース初期化ファイルに設定したバイト数と等しくなります。

SVRMGR> select * from v$sgastat;

POOL        NAME                            BYTES
----------- -------------------------- ----------
            fixed_sga                       69424
            db_block_buffers              2048000
            log_buffer                     524288
shared pool free memory                  22887532
shared pool miscellaneous                  559420
shared pool character set object            64080
shared pool State objects                   98504
shared pool message pool freequeue         231152
shared pool PL/SQL DIANA                  2275264
shared pool db_files                        72496
shared pool session heap                    59492
shared pool joxlod: init P                   7108
shared pool PLS non-lib hp                   2096
shared pool joxlod: in ehe                4367524
shared pool VIRTUAL CIRCUITS               162576
shared pool joxlod: in phe                2726452
shared pool long op statistics array        44000
shared pool table definiti                    160
shared pool KGK heap                         4372
shared pool table columns                  148336
shared pool db_block_hash_buckets           48792
shared pool dictionary cache              1948756
shared pool fixed allocation callback         320
shared pool SYSTEM PARAMETERS               63392
shared pool joxlod: init s                   7020
shared pool KQLS heap                     1570992
shared pool library cache                 6201988
shared pool trigger inform                  32876
shared pool sql area                      7015432
shared pool sessions                       211200
shared pool KGFF heap                        1320
shared pool joxs heap init                   4248
shared pool PL/SQL MPCODE                  405388
shared pool event statistics per sess      339200
shared pool db_block_buffers               136000
java pool   free memory                  30261248
java pool   memory in use                19742720
37 rows selected.

メモリー不足エラーの修正

クラスのロード中にメモリー不足になると、エラーが何も表示されずにロードが失敗し、データベースに無効なクラスが残されます。無効なクラスをコールまたは解決しようとすると、実行時にClassNotFoundExceptionインスタンスまたはNoClassDefFoundExceptionインスタンスがスローされます。破損したクラス・ファイルをロードしようとした場合も同じ例外が発生します。この場合には次の処置を実行してください。

  • サーバーにロードするセットに、実際にクラスが含まれていることを検証します。

  • loadjava -forceオプションを使用して、新しいクラスをロードすることによって、サーバーにすでに常駐しているクラスを強制的に置き換えます。

  • loadjava -resolveオプションを使用して、ロード・プロセス時にクラスの解決を試みます。これによって、実行時ではなくロード時に、欠落しているクラスを捕捉できます。

  • 新しくロードされたクラスの状態を再確認するために、そのクラスが含まれているスキーマのデータベースに接続して、次のように実行します。

    SELECT * FROM user_objects WHERE object_name = dbms_java.shortname('');
    

    STATUSフィールドにVALIDと表示されていることを確認してください。loadjavaツールからメモリーの問題や接続を失うなどの障害が発生した場合は、SHARED_POOL_SIZEおよびJAVA_POOL_SIZEを増やして再試行してください。

Javaコールおよびセッション・ヒープ統計情報の表示

データベース・パフォーマンス・ビューv$sesstatは、多数のJavaメモリー使用量統計情報を記録します。この統計情報は、Javaコール中に頻繁に更新されます。次の例は、SIDが102のデータベース・セッションのJavaコールの戻り値とセッション・ヒープ統計情報を示します。

SQL> select s.sid, n.name p_name, st.value from v$session s, v$sesstat st, v$statname n where s.sid=102 
 and s.sid=st.sid and n.statistic# = st.statistic# and n.name like 'java%';

 SID P_NAME                                        VALUE
   ---------- ---------------------------------------- ----------
          102 java call heap total size                   6815744
          102 java call heap total size max               6815744
          102 java call heap used size                     668904
          102 java call heap used size max                 846920
          102 java call heap live size                     667112
          102 java call heap live size max                 704312
          102 java call heap object count                   13959
          102 java call heap object count max               17173
          102 java call heap live object count              13907
          102 java call heap live object count max          14916
          102 java call heap gc count                      432433
          102 java call heap collected count            123196423
          102 java call heap collected bytes           5425972216
          102 java session heap used size                  444416
          102 java session heap used size max              444416
          102 java session heap live size                  444416
          102 java session heap live size max              444416
          102 java session heap object count                    0
          102 java session heap object count max                0
          102 java session heap live object count               0
          102 java session heap live object count max           0
          102 java session heap gc count                        0
          102 java session heap collected count                 0
          102 java session heap collected bytes                 0
   
   24 rows selected.