この章では、レイテンシを低下させるためにOracle JRockit JVMをチューニングする方法について説明します。
全体のスループットは良好でも、長いレイテンシが原因でパフォーマンスが低下するアプリケーションもあります。たとえば、トランザクションベースのシステムの場合、指定時間内に実行されるトランザクション数という点では適切に処理が行われているように見えますが、低い負荷でもトランザクションがタイムアウトして均等な動作にならないことがあります。アプリケーションまたはアプリケーションの実行環境でレイテンシが発生すると、このようにパフォーマンスが不均等になったり低下する場合があります。Javaコード内の競合によって発生するすべての事象がレイテンシの原因となる可能性があり、データベース・サーバーへのネットワーク接続が遅くなります。レイテンシは、どのようにJVMがチューニングされているかに応じて、JVMによって発生する場合(ガベージ・コレクション中など)もあります。
この章の内容は次のとおりです。
アプリケーション開発者は独自の手法を用いて、各自のアプリケーションのパフォーマンスを測定します。たとえば、シミュレートした一連のユース・ケースを実行して、その実行にかかった時間、1分間に実行された特定の種類のトランザクション数、平均トランザクション時間、特定のしきい値を上回るまたは下回るトランザクション時間の割合などを測定できます。レイテンシを低下させるためにチューニングするときは、特定のしきい値を上回るトランザクション時間を測定することが最大の関心事になります。最適なチューニング結果を得るためには、できるかぎり現実的で多様なベンチマークを用意し、実行時間を長くする必要があります。多くの場合、最短の実行時間は20分間です。数時間実行しないと、チューニングの効果を完全に確認できないこともあります。
長いレイテンシが発生する状況を確認したら、次の方法を使用してJRockit JVMのモニターを開始することができます。
製品に付属するJRockitフライト・レコーダを使って、実行時分析レポートを作成します。JRockit JVMおよびOracle JRockit Mission Controlを実行中の場合、各ガベージ・コレクションによる休止に対する個々の休止時間が報告されます(1回のガベージ・コレクション中に複数の休止時間が発生する場合もあります)。JRockitフライト・レコーダ・レポートには、ガベージ・コレクション中に発生したページ・フォールトも表示されます。JRockitフライト・レコーダ・レポートの作成および分析の詳細は、Oracle JRockit Mission Controlオンライン・ヘルプを参照してください。
アプリケーションでのレイテンシの発生を監視するために、レイテンシ記録を作成できます。レイテンシ記録の作成の詳細は、Oracle JRockit Mission Controlオンライン・ヘルプを参照してください。
-Xverbose:gcpause
を指定してJVMを起動すると、JRockit JVMでガベージ・コレクションの休止時間を表示できます。
レイテンシを低下させるためにJRockit JVMをチューニングする第1段階として、ガベージ・コレクションの休止時間が短いガベージ・コレクション・モードを選択します。使用できるオプションは次のとおりです。
確定的な休止時間を優先して最適化された動的なガベージ・コレクション・モード
これは、非常に短く確定的なガベージ・コレクションの休止時間を実現するために設計されたガベージ・コレクション・モードです。Oracle JRockit Real Timeの一部として使用できます。
短い休止時間を優先して最適化された動的なガベージ・コレクション・モード
これは、短いガベージ・コレクションの休止時間を実現するために設計されたガベージ・コレクション・モードです。
この静的なガベージ・コレクション・モードでは、ガベージ・コレクションの休止時間が非常に短くなりますが、特定の目標休止時間を優先した最適化は行いません。このガベージ・コレクタを選択した場合は、さらにナーサリ・サイズおよび圧縮のチューニングが必要になることもあります。
ガベージ・コレクタのオプションの詳細は、4.2項「ガベージ・コレクタの選択とチューニング」を参照してください。
レイテンシを最小限にする必要があるアプリケーション(電気通信業界や金融業界で使用するアプリケーションなど)の場合、一般的なガベージ・コレクション方式による予測不可能な休止時間は利用できません。このような長い休止時間を回避するため、JRockit JVMでは動的なガベージ・コレクション・モードである確定的なガベージ・コレクションが導入されました。これにより、ガベージ・コレクションの休止時間が短く確定的なものとして維持されます。
deterministic
ガベージ・コレクタを次のように設定します。
java -Xgc:deterministic -Xms:1g -Xmx:1g myApplication
ガベージ・コレクタは、ガベージ・コレクションの休止時間を所定の目標休止時間以内に抑えることを目指します。この目標の成否は、アプリケーションおよびハードウェアによって異なります。たとえば、ヒープが1GBで、コレクション時のライブ・データが平均で30%以下のアプリケーションを次のハードウェアで実行する場合、目標休止時間は30ミリ秒で検証されます。
2 x Intel Xeon 3.6GHz、2MBレベル2キャッシュ、4GB RAM
4 x Intel Xeon 2.0GHz、0.5MBレベル2キャッシュ、8GB RAM
低速なハードウェアでアプリケーションを実行している、ヒープ・サイズが異なる、ライブ・データが多いなどの条件下では、確定的な動作が維持されなかったり、時間の経過に応じてパフォーマンスが低下するおそれがあります。高速なハードウェアを使用するか、ライブ・データを少なくすると、目標休止時間を低く設定することができます。
deterministic
モードの目標休止時間はデフォルトで30ミリ秒に設定されていますが、-XpauseTarget:
time
オプションを使用して変更することもできます。
例:
java -Xgc:deterministic -Xms:1g -Xmx:1g -XpauseTarget:40ms MyApplication
このコマンドによって、確定的かつ短い休止時間と、目標休止時間の40ミリ秒を優先して最適化されたガベージ・コレクション・モードでJVMが起動します。
詳細は、-XpauseTarget
のドキュメントを参照してください。
確定的なガベージ・コレクタは、所定の目標休止時間を優先して圧縮を最適化し、ナーサリを使用しません。したがって、確定的なガベージ・コレクタを使用する場合は、圧縮およびナーサリ・サイズをチューニングする必要がありません。
短い休止時間を優先して最適化された動的なガベージ・コレクション・モードは、確定的なガベージ・コレクタが保証するほど短く確定的な休止時間を必要としないアプリケーションの場合に役立ちます。このガベージ・コレクション・モードでは、ガベージ・コレクションの休止時間を所定の目標休止時間(デフォルトは500ミリ秒)未満に抑えるようにガベージ・コレクション方式を選択します。圧縮によって発生する休止時間を抑えるように、圧縮も自動的に調整されます。
pausetime
の優先順位は次のように設定します。
java -Xgc:pausetime myApplication
pausetime
の優先順位の使用時にデフォルト(500ミリ秒)では長すぎるとわかった場合は、-XpauseTarget
オプションを使って休止時間の目標値を指定できます。
例:
java -Xgc:pausetime -XpauseTarget=200ms myApplication
短い休止時間と、アプリケーションのスループットは両立しません。ガベージ・コレクションの休止時間を短くすると、ブックキーピングのオーバーヘッドが増加することになり、パフォーマンスを低下させる断片化がさらに発生する場合があります。アプリケーションで500ミリ秒より長い休止時間を許容できる場合、アプリケーションのパフォーマンスを向上させるために目標休止時間を増やすことができます。
目標値は休止時間の達成目標として、動的なガベージ・コレクタが自身をより正確に構成し、休止時間を目標値に近づけるために使用されます。このオプションを使用すると、200ミリ秒から5秒の間で目標休止時間を指定できます。目標休止時間を指定しない場合、デフォルトは500ミリ秒のままになります。
短い休止時間を優先するガベージ・コレクション・モードでは、所定の目標休止時間を目指して圧縮を最適化します。そのため、追加で圧縮をチューニングする必要はありません。ナーサリ・サイズはこのガベージ・コレクション・モードに対して静的であるため、手動によるチューニングが必要になります。
静的なガベージ・コレクタを使用していても休止時間を最低限にする必要がある場合は、コンカレント・ガベージ・コレクタを使用します。一般に、世代別ガベージ・コレクタを使用する方が、シングル・スペース・ガベージ・コレクタを使用するよりも有利です。なぜなら、世代別ガベージ・コレクタの方が、より高いアプリケーションのスループットが得られるからです。
世代別コンカレント・ガベージ・コレクタを使用するには、次のコマンド・ラインを入力します。
java -Xgc:gencon myApplication
シングル・スペース・コンカレント・ガベージ・コレクタを使用するには、次のコマンド・ラインを入力します。
java -Xgc:singlecon myApplication
静的なガベージ・コレクタを使用するときは、ナーサリ・サイズと圧縮を手動でチューニングする必要があります。
ヒープ・サイズを変更するには、JRockit JVMの起動時にコマンドライン・オプションの-Xms
(初期最小ヒープ・サイズ)と-Xmx
(最大ヒープ・サイズ)を使用します。通常、初期ヒープ・サイズと最大ヒープ・サイズは同じ値に設定できます。ヒープ・サイズを大きくすると、ガベージ・コレクションの頻度が少なくなります。また、ヒープが大きくなると、ガベージ・コレクションにかかる時間は若干長くなりますが、一般にヒープ・サイズが数ギガバイトに達するまでは、それほど大きな影響はありません。
ヒープ・サイズをチューニングする最適なアプローチは、様々なヒープ・サイズを使用してアプリケーションのベンチマークを測定することです。6.1項「レイテンシの測定」に従ってガベージ・コレクションの休止時間を監視して、アプリケーションの指定可能な最大ヒープ・サイズを決定します。
唯一の例外となるのが、確定的なガベージ・コレクタです。確定的なガベージ・コレクタは、約1GBのヒープ・サイズで動作が最適になることが検証されます。
ヒープ・サイズを設定するには、-Xms
および-Xmx
のオプションを使用します。
例:
java -Xms:1g -Xmx:1g myApplication
詳細は、4.4項「メモリー割当てのパフォーマンスの最適化」を参照してください。
-Xgc:pausetime
または-Xgc:gencon
を実行している場合、ナーサリ・サイズを手動でチューニングできます。
-Xgc:pausetime
を使用する場合、ナーサリのサイズは静的ですが、ナーサリのサイズを手動で設定すると動作がより均等になります。デフォルトのナーサリ・サイズの詳細は、『Oracle JRockitコマンドライン・リファレンス』の-Xnsに関するドキュメントを参照してください。動的なガベージ・コレクタを使用している場合、シングルスペース・ガベージ・コレクションの使用中は、ナーサリが完全に無効になる可能性があります。
注意: 多くの場合、ナーサリ・サイズを手動でチューニングすると、休止時間とアプリケーション・スループットの両方に有益です。 |
-Xgc:gencon
のデフォルト・ナーサリ・サイズは静的であるため、すべてのアプリケーションに最適な値ではないことがあります。カスタム・ナーサリ・サイズを手動で設定すると効果的な場合があります。ナーサリはできるかぎり大きくする必要がありますが、若いコレクション(ナーサリ・ガベージ・コレクション)によって生じる休止時間が長すぎる場合は、ナーサリ・サイズを減らしてください。6.1項「レイテンシの測定」に示すように、ガベージ・コレクションの休止時間を監視しながら、いくつかの異なるナーサリ・サイズを使用してアプリケーションのベンチマークを測定し、ナーサリ・サイズをチューニングします。
ナーサリのサイズを設定するには、-Xns
オプションを使用します。
例:
java -Xgc:pausetime
-Xns:64m myApplication
静的なガベージ・コレクタの使用時は、圧縮を手動でチューニングするとレイテンシを改善できます。圧縮は、ガベージ・コレクションの休止時間中に実行されるため、圧縮時間はガベージ・コレクションの休止時間に影響します。デフォルトで、静的なガベージ・コレクタは、圧縮時間を均等に保つことを目指す圧縮方式を使用しますが、圧縮時間に上限は設けません。
圧縮を手動で制限するには、静的な圧縮領域サイズを設定する(-XXcompaction
)、または圧縮によって更新される可能性のある参照数を制限する(-XXcompaction:maxReferences
)ことができます。どちらの方法を使用しても、圧縮時間の上限は保証されませんが、圧縮時間が長くなるリスクは減少します。
圧縮率を低く設定すると、ヒープでは断片化が徐々に進行し、最後にはオブジェクトの割当てが可能な空き領域を見つけられなくなるので注意してください。ヒープは、ダーク・マター(基本的には重度の断片化)で一杯になります。この状態に陥ると、ヒープ全体の完全な圧縮が実行されます。その結果、最長で30秒間の休止時間が生じます。ダーク・マターは、フライト・レコーダ記録にヒープ関連の情報として報告されます。
圧縮の制限の詳細は、4.3.2項「圧縮を調整する」を参照してください。
-XXgcTrigger
オプションを使って、ヒープの空き領域がどこまで減った時点でコンカレント・ガベージ・コレクションを開始するかを設定できます。コンカレント・ガベージ・コレクション中にヒープが一杯になると、Javaアプリケーションはガベージ・コレクションがメモリーを解放するまでメモリーを割り当てることができません。このため、アプリケーションは休止状態になります。ヒープが一杯にならないようにトリガー値は実行時に自動的にチューニングされますが、この自動のチューニングに時間がかかりすぎることがあります。この機能に頼らずに、-XXgcTrigger
を使って、ガベージ・コレクションのトリガー値をアプリケーションに適した値に最初から設定できます。
コンカレント・マーク・フェーズの途中でヒープが一杯になると、スイープ・フェーズはパラレル・スイープに戻ります(-XXnoParSweep
を指定した場合を除く)。この動作が頻繁に起こり、これを回避するためにガベージ・コレクションのトリガー値が自動的に増えない場合、-XXgcTrigger
を使ってガベージ・コレクションのトリガー値を手動で増やしてください。
例:
java -XXgcTrigger
myApp
ガベージ・コレクションの現在のトリガー値は、トリガー値が変わった時点での-Xverbose:memdbg
出力に表示されます。