アプリケーション・サーバーは Java ベースのプロセスであり、アプリケーション・サーバーで稼働する Java アプリケーションを実行およびサポートするには、Java 仮想マシン (JVM) 環境が必要です。 Java ランタイム環境を構成し、パフォーマンスおよびシステム・リソース使用率を 調整することができます。
z/OS プラットフォームでは、コントローラーとサーバントの両方に JVM があります。 ここに記載された情報は、サーバントの JVM に適用されます。 通常、コントローラーの JVM は調整する必要がありません。
Java ランタイム環境には、WebSphere Application Server などの Java ベース・アプリケーションおよびサーバーの実行環境が用意されています。 したがって、WebSphere Application Server およびそこで稼働するアプリケーションのパフォーマンスやシステム・リソース消費量を判別する場合に、Java 構成が重要な役割を果たします。
IBM Java 5.0 以上のバージョンの主な改良点は、IBM の初期 Java 実行テクノロジーのパフォーマンスおよび保守容易性を大幅に強化する仮想マシン・テクノロジーです。 この新規テクノロジーのについて詳しくは、http://www.ibm.com/software/webservers/appserv/was/performance.htmlを参照してください。
ご使用のアプリケーション・サーバーが稼働している JVM プロバイダーを判別するには、アプリケーション・サーバーの app_server_root/java/bin ディレクトリーから java –fullversion コマンドを発行します。 アプリケーション・サーバーはこのコマンドに応答して、JVM プロバイダー情報を含む、JVM に関する情報を SystemOut.log ファイルに書き込みます。
JVM 調整は使用する JVM プロバイダーに依存していますが、すべての JVM に該当する一般の調整概念もあります。 これらの一般概念には、以下のものがあります。
以下のステップでは、JVM ごとに以下のタイプの調整を実行するための具体的な手順を示します。 これらのステップは、特定の順序で実行する必要はありません。
「構成」タブの「一般プロパティー」セクションで、「JIT を使用不可にする」が選択されていないことを確認してください。
開発環境など一部の環境では、ランタイム・パフォーマンスではなく、アプリケーション・サーバーの開始パフォーマンスを最適化することがより重要です。 別の環境では、ランタイム・パフォーマンスを最適化することがより重要になります。 デフォルトで、IBM JVM はランタイム・パフォーマンスが最適化され、HotSpot ベース の JVM は開始パフォーマンスが最適化されています。
Java JIT コンパイラーは、開始およびランタイムのパフォーマンスが最適化されるかどうかに大きく影響します。 コンパイラーで使用される初期の最適化レベルは、クラス・メソッドのコンパイルにかかる時間と、 サーバーの開始にかかる時間に影響を与えます。 開始を速めるには、コンパイラーで使用される初期の最適化レベルを低くする必要があります。 ただし、初期の最適化レベルを低くすると、クラス・メソッドが低い最適化レベルでコンパイルされるため、アプリケーションのランタイム・パフォーマンスが低下する可能性があります。
この設定値は、IBM JVM が低い最適化レベルをクラス・メソッド・ コンパイルに使用する方法に影響します。最適化レベルを低くすると、サーバ開始時間が短縮されますが、ランタイム・パフォーマンスは低下します。 このパラメーターが 指定されていない場合、IBM JVM はデフォルトでコンパイルに高い初期最適化レベルを使用して開始するため、ランタイム・パフォーマンスは向上しますが、サーバーの開始時間が長くなります。
デフォルト: | 高い初期コンパイラー最適化レベル |
推奨: | 高い初期コンパイラー最適化レベル |
使用法: | -Xquickstart はサーバー開始時間を短縮します。 |
-Xquickstart -Xverify:none
Java ヒープ・パラメーターは、ガーベッジ・コレクションの動作に影響します。 ヒープ・サイズを増やすと、より多くのオブジェクトを作成することができます。大きなヒープは満杯になるまでに時間がかかるので、 ガーベッジ・コレクションが実行されるまでにアプリケーションが 稼働する時間が長くなります。 ただし、大きなヒープは圧縮にも時間がかかるので、ガーベッジ・コレクションの所要時間が長くなります。
developerWorks Web サイトで入手可能な「IBM Developer Kit and Runtime Environment, Java2 Technology Edition, Version 5.0 Diagnostics Guide」には、ヒープ・サイズ調整に関する追加情報が記載されています。
Java ヒープ情報は SMF レコードに含まれており、 コンソール・コマンド DISPLAY,JVMHEAP で動的に表示することができます。
管理コンソールを使用して、ヒープ・サイズを構成するには、次のようにします。
両方の設定を調整する必要がある場合も、両方のフィールドで値を指定することができます。
パフォーマンス分析のためには、初期ヒープ・サイズと最大ヒープ・ サイズを等しくします。
初期ヒープ・サイズの設定は、 ガーベッジ・コレクションの実行頻度を MB 単位で指定します。最大ヒープ・サイズの設定は、ガーベッジ・コレクションの実行頻度を指定します。 これらの設定は、いずれもパフォーマンスに重大な影響を及ぼします。
Java アプリケーションの作業セット・サイズが不明な実動システムを調整する場合は、 初期ヒープ・サイズを、まず、最大ヒープ・サイズの 25% にするとよいでしょう。 これにより、JVM はヒープのサイズをアプリケーションの作業セットのサイズに適合させようとします。
この図は、3 つの CPU プロファイルを示し、 それぞれ固定ワークロードで Java ヒープ設定値を変えながら稼働しています。 中央のプロファイルでは、初期ヒープ・サイズと最大ヒープ・サイズは 128MB に設定されています。ガーベッジ・コレクションは 4 回行われています。ガーベッジ・コレクションの合計時間は、合計実行時間の約 15% です。 ヒープ・パラメーターを倍の 256MB にすると、一番上のプロファイルのように、 ガーベッジ・コレクション間の作業時間の長さが増えていきます。 ガーベッジ・コレクションは 3 回しか行われませんが、それぞれのガーベッジ・コレクションの長さも増大しています。3 番目のプロファイルでは、ヒープ・サイズが 64MB に削減され、逆の結果が示されています。ヒープ・サイズが小さくなると、ガーベッジ・コレクション間の時間と個々のガーベッジ・コレクションの時間は、どちらも短くなります。 これらの 3 つの構成すべてについて、ガーベッジ・コレクションの合計時間 は、約 15% です。 この例は、Java ヒープおよびそれとオブジェクト使用率との関係について重要な概念 を示しています。Java アプリケーションには、 常にガーベッジ・コレクションのコストがかかります。
ヒープのフリー・スペースが 85% 以上で安定している場合は、アプリケーション・サーバーおよびアプリケーションがヒープに割り振られたメモリーをあまり使用していないため、ヒープ・サイズの最大値を小さくすることを検討してください。
64 ビット・モードで実行するように構成された サーバーがある場合、これらのサーバーにデフォルト設定より大幅に大きい JVM 最大ヒープ・サイズを 指定できます。 例えば、サーバーが 64 ビット・モードで実行するように構成されている場合、 コントローラーおよびサーバントに対して初期最大ヒープ・サイズ 1844m を 指定できます。
以下のコマンド行パラメーターを使用して、これらの設定を調整することもできます。 以下のパラメーターは、サポートされているすべての JVM に適用され、 各アプリケーション・サーバーまたはアプリケーション・サーバー・インスタンスの最小および最大ヒープ・サイズを 調整するために使用されます。
この設定は、Java ヒープの初期サイズを制御します。 このパラメーターを適切に調整すると、ガーベッジ・コレクションのオーバーヘッドが削減され、 サーバーの応答時間とスループットが改善されます。 アプリケーションによっては、このオプションのデフォルト設定は低すぎるため、多数の小さなガーベッジ・コレクションが発生します。
デフォルト: | 50 MB。このデフォルト値は、31 ビットおよび 64 ビットの構成の両方に適用されます。 |
推奨: | ワークロードに固有ですが、デフォルトより大きい値にします。 |
使用法: | -Xms256m は初期ヒープ・サイズを 256 メガバイトに設定します。 |
この設定は、Java ヒープの最大サイズを制御します。 このパラメーターを大きな値に設定すると、アプリケーション・サーバーで使用可能なメモリーが増え、ガーベッジ・コレクションの頻度が小さくなります。 この設定を大きくすると、サーバーの応答時間およびスループットを改善することができます。 ただし、この設定を大きくすると、ガーベッジ・コレクションが発生した場合の所要時間も増加します。 この設定値は、アプリケーション・サーバー・インスタンスで使用可能なシステム・メモリーよりも大きな値に設定しないでください。 使用可能なシステム・メモリーよりも設定値を大きくすると、システムのページングが発生し、パフォーマンスが著しく低下することがあります。
デフォルト: | 256 MB。このデフォルト値は、31 ビットおよび 64 ビットの構成の両方に適用されます。 |
推奨: | ワークロードに固有ですが、使用可能な物理メモリー・サイズに応じてデフォルトより 大きい値にします。 |
使用法: | -Xmx512m は、最大ヒープ・サイズを 512 メガバイトに設定します。 |
この設定を IBM JVM で使用し、ラージ・ページ (16 MB) を使用してヒープを割り振ります。 ただし、この設定を使用する場合、ご使用のオペレーティング・システムが ラージ・ページをサポートするよう構成されている必要があります。 ラージ・ページを使用すると、ヒープ・メモリーの追跡に必要となる CPU オーバーヘッドを削減することができ、 より大きなヒープを作成することもできます。
オペレーティング・システムの調整についての詳細は、オペレーティング・システムの調整 を参照してください。
この設定を IBM JVM で使用すると、64 キロバイトのページ・サイズ (ミディアム・ページ) を使用してヒープを割り振ることができます。 アプリケーションに必要なメモリーにこの仮想メモリー・ページ・サイズを使用すると、ラージ・ページ・サイズに関連したハードウェアが効率化されるため、アプリケーションのパフォーマンスおよびスループットを改善できます。
64 KB のページ・サイズをサポートするには、管理コンソールで「サーバー」>「アプリケーション・サーバ」>「server_name」>「プロセス定義」>「環境エントリー」>「新規」をクリックしてから、「名前」フィールドで LDR_CNTRL を、「値」フィールドで DATAPSIZE=64K@TEXTPSIZE=64K@STACKPSIZE=64K を指定します。
デフォルト: | 4 KB |
推奨: | -Xlp64k は 64 KB ページ・サイズをサポートします。 |
JVM ランタイムのカウンターを監視することによって、アプリケーションがオブジェクトを乱用しているかどうかを確認できます。Java 仮想マシン・プロファイラー・インターフェース (JVMPI) カウンターを 使用可能にするには、-XrunpmiJvmpiProfiler コマンド行オプションとともに 、JVM モジュールの最大レベルも設定しなければなりません。ガーベッジ・コレクション間の平均時間は、最もよい結果が出た場合で、ガーベッジ・コレクション 1 回分の平均所要時間の少なくとも 5 から 6 倍です。この数値に達しない場合、アプリケーションがガーベッジ・コレクションに費やす時間は、実行時間の 15% を超えています。
ガーベッジ・コレクションのボトルネックを示す情報がある場合、 ボトルネックを解消する方法は 2 つあります。 アプリケーションを最適化する最も経済的な方法は、オブジェクト・キャッシュとプールをインプリメントすることです。 Java プロファイラーを使用して、ターゲットにするオブジェクトを 決定します。アプリケーションを最適化できない場合は、メモリー、プロセッサー、およびクローンの追加が役に立つことがあります。 メモリーを追加することによって、各クローンが妥当なヒープ・サイズを維 持できるようになります。プロセッサーを追加すると、 クローンを並列に実行できます。
メモリー・リークは、Java 言語ではガーベッジ・コレクションのボトルネックの原因となる危険な状況です。 メモリー・リークは最終的にシステムの不安定性につながるため、メモリーの過剰使 用よりも有害です。時間が経過するにつれて、ガーベッジ・コレクションが頻繁に発生し、 最終的にはヒープが使い尽くされて、Java コードは致命的なメモリー不足例外により停止します。 メモリー・リークは、使われていないオブジェクトが参照され、解放されないときに起こります。 メモリー・リークは、Hashtable などの集合クラスでよく発生します。 これは、この表が実際の参照情報が削除された後であっても、常にオブジェクトを参照していることが原因です。
ワークロードが高いと、アプリケーションが、実稼働環境でのデプロイメント直後に破損することが頻繁に起こります。このような状況は、リークを起こしているアプリケーションで、ワークロードの高さがリークの拡大を加速し、メモリー割り振りの失敗が生じる場合に特に顕著です。
メモリー・リークの問題は、一定の期間を経てからでないと表面化しないため、メモリー・リークは長期間実行するテストでは検出されやすいと言えます。 短期間の稼働テストでは誤った警告を受ける可能性があります。Java 言語では、いつメモリー・リークが発生しているかを認識しにくい場合があります。メモリーの使用が突然に、あるいは一定の期間内に単調に増加したように見える場合には、特に判断がむずかしいでしょう。 メモリー・リークの検出がむずかしいのは、このような増加が妥当なものであったり、開発者が意図的に行ったものであったりする可能性があるためです。 後になって使用されるオブジェクトと、まったく使用されないオブジェクトとを区別する方法は、アプリケーションを長期間実行していればわかってきます。 長期間実行するアプリケーションのテストでは、実際にオブジェクトが後になって使用されているかどうかについて、 より確信が持てるようになります。
多くの場合、同じテスト・ケースを続けて反復する場合に、メモリー・リークの問題が起こります。メモリー・リークのテストのゴー ルは、使用不能なメモリーと使用中のメモリーとの間で、相対的サイズに大きなギャッ プを作り出すことです。同じシナリオを何度も繰り返すことによって、このギャップは非常に累進的に増えていきます。このテストは、テスト・ケースの実行により発生するリーク数がごくわずかであるために、1 回の実行ではほとんど検出できないような場合に役立ちます。
反復テストは、システム・レベルまたはモジュール・レベルで使用できま す。モジュラー・テストの利点は、管理の点でより優れていることです。モジュールが、専用のモジュールを保持して、メモリーの使用など外部の副次作用が発生しないように設計されている場合、メモリー・リークのテストは簡単になります。最初に、モジュールを実行する前のメモリー使用量が記録されます。次に、固定セットのテスト・ケースが 繰り返し実行されます。テスト実行の終了時には、現在のメモリー使用量が記録され、顕著な変化がないかどうかチェックされます。実際のメモリー使用量を記録するときには、ガーベッジ・コレクションを行う必要があることを覚えておいてください。これを行うには、ガーベッジ・コレクションを実行したいモジュールに System.gc() を挿入するか、このイベントを強制的に発生させるプロファイル作成ツールを使用します。
一部のメモリー・リーク問題は、アプリ ケーションでいくつかのスレッドが実行中の場合にのみ起こる可能性があります。 残念なことに、プログラム・ロジックの複雑さが増したため、同期点からメモリー・リークが発生することが非常に多くなっています。プログラミング時に注意を怠ると、参照が保持されたままになったり、解放されなかったりする可能性があります。メモリー・リークの問題は、システムの並行性が 増すことによって、促進されたり、加速されたりすることがよくあります。 並行性を高める最も一般的な方法は、テスト・ドライバー内のクライアント数を増やすことです。
ヒープの消費が、ワークロードが高いときにリークが起こった可能性を示している (アプリケーション・サーバーの CPU 使用率が常に 100% 近くなっている) のに、その後、ワークロードが低いかほとんどアイドル状態になったときにはヒープが回復するように見えるのは、ヒープのフラグメント化が起きている兆候です。ヒープのフラグメント化は、JVM がガーベッジ・コレクションのサイクル中にメモリー割り振り要求を満たすために十分な量のオブジェクトを解放することができたとしても、ヒープ内の小さな空きメモリー域を圧縮して、連続した大きなスペースを作成する時間がない場合には、起こる可能性があります。
この他に、ヒープのフラグメント化は、小さなオブジェクト (512 バイト未満) が解放された場合にも起こります。オブジェクトが解放されても、ストレージは回復しません。この結果、ヒープ圧縮が実行されるまでは、メモリーのフラグメント化が進みます。
ヒープのフラグメント化は圧縮を強制するによって削減できますが、これを行う場合パフォーマンス・ペナルティーがあります。 Java -X コマンドを使用して、メモリー・オプションのリストを参照します。
Java 仮想マシン (JVM) は、 並列ガーベッジ・コレクターを使用して、大部分のガーベッジ・コレクション・サイクルの間に、 SMP を最大限に活用します。HotSpot ベース JVM には、単一スレッドのガーベッジ・コレクターがあります。
Java ガーベッジ・コレクションをテストすることによって、 アプリケーションがどのようにメモリーを使用するかが理解できます。 ガーベッジ・コレクションは Java の強みです。アプリケーション作成者からメモリー管理の負担をなくす ことによって、Java アプリケーションは、ガーベッジ・コレクション機能を持たない言 語で作成されたアプリケーションよりも堅固になっています。ただし、この堅固さが生かされるのは、アプリケーションがオブジェクトを 過剰に使用していない場合に限ります。 ガーベッジ・コレクションは通常、適切に機能するアプリケーションの合計実行時間の 5% から 20% を消費します。管理を行わない場合、ガーベッジ・コレクションはアプリケーションにとって最大のボトルネックの 1 つになります。
固定ワークロードの実行中にガーベッジ・コレクションをモニターすることによって、 アプリケーションによるオブジェクトの使用が過剰になっているかどうかが分かります。 ガーベッジ・コレクションによって、メモリー・リークがあるかどうか検出することもできます。
JVM 設定を使用して、ガーベッジ・コレクションのタイプおよび動作を構成することができます。 連続スペースがないために JVM が現在のヒープからオブジェクトを割り振ることができない場合、ガーベッジ・コレクターが呼び出されて、使用されていない Java オブジェクトのメモリーが再利用されます。 JVM ベンダーごとに、固有のガーベッジ・コレクター・ポリシーおよび調整パラメーターがあります。
管理コンソールで Verbose ガーベッジ・コレクション設定を使用して、 ガーベッジ・コレクションのモニターを有効にすることができます。 この設定の出力には、クラス・ガーベッジ・コレクション統計が含まれます。 生成されるレポートのフォーマットは、異なる JVM またはリリース・レベルの間では標準化されません。
ご使用の JVM ガーベッジ・コレクションの設定を調整するには、次のようにします。
以下のリストでは、さまざまな JVM ガーベッジ・コレクターの –X オプションについて 説明しています。
Java -X オプションを使用して、メモリー・オプションのリストを表示します。
デフォルト: | optthruput |
推奨: | optthruput |
使用法: | Xgcpolicy:optthruput は、ガーベッジ・コレクションを optthruput に設定します。 |
gcpolicy を optthruput に設定すると、並行マークが使用不可になります。 アプリケーション応答時間が安定せず、休止時間に問題があると考えられる場合を除き、optthruput ポリシーを使用するとスループットが最適になります。
gcpolicy を optavgpause に設定すると、そのデフォルト値で並行マークが使用可能になります。この設定は、 通常のガーベッジ・コレクションによって発生する、アプリケーションの不安定な応答時間を緩和します。 ただし、このオプションはスループット全体を減少させる可能性があります。
クラスのライブ・インスタンスが残されていない場合、デフォルトで、JVM はメモリーからクラスをアンロードします。 そのため、クラスをアンロードすると、パフォーマンスが低下することがあります。
-Xnoclassgc 引数を使用してクラス・ガーベッジ・コレクションを 使用不可にすることで、アプリケーションでクラスをさらに簡単に再利用できます。 クラス・ガーベッジ・コレクションをオフにすると、 同じクラスを複数回ロードおよびアンロードするオーバーヘッドが除去されます。
デフォルト: | クラス・ガーベッジ・コレクションは使用可能です。 |
推奨: | クラス・ガーベッジ・コレクションを使用不可にします。 |
使用法: | Xnoclassgc はクラス・ガーベッジ・コレクションを使用不可にします。 |
IBM Java 2 Runtime Environment (J2RE) バージョン 1.5.0 の共用クラス・オプションにより、キャッシュでクラスを共有できます。 キャッシュでクラスを共有すると、起動時間が短縮され、メモリー占有スペースを縮小できます。 アプリケーション・サーバー、ノード・エージェントおよびデプロイメント・マネージャーなどのプロセスは、この共有クラス・オプションを使用できます。
このオプションを使用すると、プロセスを使用していない場合にキャッシュをクリアする必要があります。 キャッシュをクリアするには、app_server_root/bin/clearClassCache.bat/sh ユーティリティーを呼び出すか、プロセスを停止してからそのプロセスを再始動します。
特定のプロセスに対してクラス共用オプションを使用不可にする必要がある場合は、そのプロセスに汎用 JVM 引数 -Xshareclasses:none を指定します
デフォルト: | キャッシュでのクラス共用オプションは使用可能です。 |
推奨: | キャッシュでのクラス共用オプションを使用可能のままにしておきます。 |
使用法: | -Xshareclasses:none はキャッシュでのクラス共用オプションを使用不可にします。 |
DB2 を使用する場合、HP JVM for HP-UX で SafepointPolling テクノロジーを 使用不可にすることを検討してください。Java スレッドの safepoint を確保するために開発された SafepointPolling テクノロジーを使用すると、WebSphere Application Server と DB2 データベース間でシグナル干渉を引き起こす可能性のあるシグナルが生成されます。 この干渉が発生すると、頻繁にデータベースのデッドロックが生じます。 -XX:-SafepointPolling オプションで JVM を起動し、ランタイム中の SafepoinPolling を使用不可にして、干渉が起こらないようにしてください。