長いレイテンシは、たとえば、全体のパフォーマンスは良好でも、トランザクションベースのアプリケーションで1つのトランザクションがタイムアウトして表面化することがあります。たいていの場合、不均等なパフォーマンスや確定的でないレイテンシに問題があります。
この章では、以下のトピックについて説明します。
長いレイテンシは、多くの場合、休止時間を短く確定的にするようにアプリケーションがチューニングされていないことを示します。時間のかかるトラブルシューティングや緩和対策の作業を行う前に、JVMをチューニングして休止時間を短くすることを優先してください。休止時間の短さを優先したJVMのチューニングの詳細は、『Oracle JRockitパフォーマンス・チューニング・ガイド』を参照してください。
低いレイテンシと、アプリケーション全体の高いスループットは両立しません。
トランザクションのタイムアウトを招く高いレイテンシは、多くの場合、ガベージ・コレクションによる休止によって発生します。個々のガベージ・コレクションの休止時間を減らすため、ガベージ・コレクタはモーストリ・コンカレント・モードで実行されます。つまり、ガベージ・コレクションはほとんどの場合、Javaスレッドがまだ実行中のときに行われます。これにより、ガベージ・コレクションのコンカレント・フェーズ中の変更を追跡する作業など、ガベージ・コレクタに追加の作業が発生します。また、コンカレント・ガベージ・コレクション中に割り当てられたオブジェクトのガベージ・コレクションは、次回のガベージ・コレクション・サイクルまで行われないため、ガベージ・コレクションの効率は低下します。この結果、JVMは、より頻繁にガベージ・コレクションを行うことになります。
圧縮による休止時間を短くするために-XXcompaction
コマンドライン・オプションを使用して圧縮を無効化または制限している場合、ヒープが断片化する可能性があります。(断片化はフライト・レコーダ・ツールを使用して分析できます。)
ガベージ・コレクションの休止時間を長くするか、ガベージ・コレクションを手動でチューニングすることでレイテンシを低く抑えると同時に、全体のスループットを向上できます。詳細は、『Oracle JRockitパフォーマンス・チューニング・ガイド』を参照してください。
この項では、-Xgc:deterministic
および-Xgc:pausetime
などのコンカレント・ガベージ・コレクションにほとんどの場合、関連するレイテンシの問題のトラブルシューティングに関する情報を提供します。
ガベージ・コレクション・トリガー(gctrigger
)値は、Javaスレッドがガベージ・コレクションの全プロセスを通してオブジェクト割当てを続行できるようにするため、コンカレント・ガベージ・コレクションの開始時に使用可能であることが必要な空きヒープ領域です。gctrigger
値は、コンカレント・ガベージ・コレクション中にヒープが一杯にならないようにするため、実行時に変更されます。
-Xverbose:memdbg
オプションの出力を使用するか、フライト・レコーダ・ツールを使用してgctrigger
値を監視します。
gctrigger
値が増え続ける場合は、コンカレント・ガベージ・コレクタに対してアプリケーションの負荷が高すぎます。アプリケーションの負荷を減らしてください。
gctrigger
値が増え続ける場合は、Javaヒープ・サイズが小さすぎる可能性もあります。ヒープ・サイズを大きくするとこの現象は改善されます。
-Xverbose:memdbg
オプションまたはフライト・レコーダ・ツールのどちらかを使用して、古いコレクションに対するガベージ・コレクションの理由を監視します。古いモーストリ・コンカレント・コレクションに対するガベージ・コレクションの通常の理由は、ヒープが一杯であることです。
オブジェクトの割当てに失敗して古いコレクションが頻繁にトリガーされる場合は、gctrigger
が低すぎます。-XXgcTrigger
オプションを使用してgctrigger
を増やすか、またはアプリケーションの負荷を減らしてください。
-Xverbose:gcpause
オプションの出力を使用するか、フライト・レコーダの記録から若いコレクションの休止時間を監視します。
若いコレクションの休止時間が長すぎる場合は、-Xns
オプションを使用してナーサリ・サイズを減らすか、または一世代のガベージ・コレクタを実行します。
フライト・レコーダの記録でガベージ・コレクションの休止時間を監視します。長すぎる休止時間の休止時間部分を確認します。Compaction
の休止時間部分が長すぎる場合は、目標休止時間を減らします。Mark:Final
の休止時間部分(特に、RefrenceQueues
に関する休止時間部分)が長すぎる場合、アプリケーション内のjava.lang.ref.Reference
オブジェクトが多いことが問題の原因である可能性があります。使用する参照オブジェクトの数を減らすようにJavaアプリケーションを再設計します。また、ヒープ・サイズを減らしてみることもできます。それによって、参照オブジェクトを処理する頻度が上がる一方、古いコレクションが行われるたびに処理する参照オブジェクトの量は減少します。
この項に示されている解決策を試してもパフォーマンスの低下を解決できない場合は、第9章「サポートに関するオラクルへの連絡」の説明に従ってOracleサポートにご連絡ください。