9.2 Javaのメモリー使用量について

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

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

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

  • 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の状態がこのサイズを超えそうになると、メモリー不足障害が発生します。

    ノート:

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

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

データベースのインストール・テンプレートの次のパラメータに対して、デフォルト値を設定できます。

  • JAVA_POOL_SIZE

  • SHARED_POOL_SIZE

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

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

図9-1の説明が続きます
「図9-1 Oracle JVMのメモリー・パラメータの構成」の説明

9.2.2 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プール・メモリーの総量を計算する必要があります。各UGAは必要に応じて拡大または縮小できます。ただし、UGA全体が一定のJavaプール領域に収まるようにしてください。

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

ノート:

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

Java対応セッションの数の削減

データベース内のJavaのトップレベルの起動は、クライアント側のアプリケーションまたはユーティリティによって発行されます。各クライアントに専用サーバーがある場合、大規模なデプロイメントを行うと、データベース・サーバーでリソースが大量に消費され、リソースの浪費につながります。クライアント側の接続プールまたはデータベース常駐接続プール(DRCP)を使用すると、データベース・プロセスおよびセッションの数を削減できます。

関連項目:

DRCPの詳細は、『Oracle Database JDBC開発者ガイド』を参照してください。

9.2.3 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.

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

クラスのロード中にメモリー不足になると、エラーが何も表示されずにロードが失敗し、データベースに無効なクラスが残されます。無効なクラスをコールまたは解決しようとすると、実行時に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を増やして再試行してください。

9.2.5 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.