Hitachi

uCosminexus Application Runtime - Cosminexus Developer's Kit for Java 機能解説・リファレンス


2.3.2 G1GCのチューニング

G1GCのチューニング方法について説明します。システム構築時にチューニングを実施し,システム要件を満たしていることを確認してから本番環境に適用してください。

Javaヒープ領域のサイズに関係するオプションの一覧を次の表に示します。なお,表の項番1〜8は「図2-28」の番号と対応しています。

表2‒4 Javaヒープ領域内の各領域とMetaspace領域のサイズを指定するオプション

項番

オプション名

オプションの意味

1

-Xms<size>

Javaヒープの初期サイズを設定します。※1

2

-Xmx<size>

Javaヒープの最大サイズを設定します。※1

3

-XX:NewSize=<value>

New領域の最小サイズを設定します。※2

4

-XX:MaxNewSize=<value>

New領域の最大サイズを設定します。※2

5

-XX:NewRatio=<value>

Javaヒープ領域に対するNew領域の割合を設定します。※2

<value>が2の場合は,New領域とTenured領域の割合が,1:2になります。

6

-XX:SurvivorRatio=<value>

New領域に対するSurvivor領域で最大に取ることができる領域サイズの割合を設定します。

Survivor領域の最大で取ることができる領域サイズは次の式で求められます。

(Survivor領域のサイズ)※3=(New領域のサイズ)/SurvivorRatio

7

-XX:MetaspaceSize=<size>

Metaspace領域の初期サイズを設定します。※4

8

-XX:MaxMetaspaceSize=<size>

Metaspace領域の最大サイズを設定します。※4

注※1

-Xmsと-Xmxの値は同じ値を指定することを推奨します。

注※2

項番3〜5のオプションを指定した場合,New領域のリサイズが制限され,目標停止時間内にGC停止時間を抑えようとするG1GCのメリットを損なうため,G1GCでは指定しないことを推奨します。また,項番3〜5のオプションを指定しなかった場合,New領域の初期サイズはJavaヒープの初期サイズ×0.2のサイズが確保され,Eden領域の初期サイズはSurvivorRatioのデフォルト値である8に従って割り当てられます。

注※3

Survivor領域のサイズとはTo空間またはFrom空間のサイズを指します。To空間とFrom空間の合計サイズではないことに注意してください。

注※4

-XX:MetaspaceSizeと-XX:MaxMetaspaceSizeの値は同じ値を指定することを推奨します。

図2‒28 Javaヒープ領域内の各領域とMetaspace領域のサイズとオプションの対象範囲

[図データ]

G1GCのチューニングに利用するオプションを次の表に示します。各オプションの詳細については,「5.4 日立JavaVMで指定できるJava HotSpot VMのオプション」の各オプションの説明を参照してください。

表2‒5 G1GCのチューニングオプション

項番

オプション名

デフォルト値

オプションの意味

1

-XX:MaxGCPauseMillis=<value>

200

目標停止時間[ms]

2

-XX:ParallelGCThreads=<value>

CPU数

(OSが認識しているCPU数)

Evacuationの処理をするスレッド数

3

-XX:ConcGCThreads=<value>

(ParallelGCThreads + 2) / 4

CM処理をするスレッド数

注※

実行環境のCPU数によって計算式が異なります。

〈この項の構成〉

(1) チューニングの流れ

チューニングの全体の流れを次の図に示します。

図2‒29 チューニングの全体の流れ

[図データ]

次から,それぞれのチューニングの詳細を説明します。

(2) 初期検証

初期検証の流れを次の図に示します。

図2‒30 初期検証の流れ

[図データ]

  1. G1GCを有効にしてシステムの検証をします。検証の結果,システム要件を満たしている場合でも,FullGCの発生傾向がないかどうかを確認します。システム要件を満たしていない場合は,「(3) FullGCの発生を抑止するチューニング」へ進んでください。

  2. 検証中にFullGCが発生していない場合でも,システムを長期間動かすことで,将来FullGCが発生する場合があります。そのため,FullGCの発生傾向がないかどうかを確認します。

    FullGCの発生傾向のイメージを次の図に示します。

    図2‒31 FullGCの発生傾向のイメージ

    [図データ]

    この図は検証中のGC後の使用量をグラフにしたイメージです。この図のようにMixedGCが発生していても,Javaヒープ使用量が長期的には単調増加している場合,FullGCの発生傾向があります。

  3. システム要件を満たしている場合でも,FullGCの発生傾向があった場合,検証時間を延ばしFullGCを発生させ,FullGCが発生してもシステム要件が満たしているかどうかを確認します。FullGCを発生させた結果,システム要件を満たさなくなった場合は,FullGCの発生を抑止するチューニングをします。また,検証時間を延ばすことができない場合は,FullGCが発生していなくても,FullGCの発生を抑止するチューニングをし,FullGCの発生傾向をなくしてください。FullGCの発生を抑止するチューニングについては,「(3) FullGCの発生を抑止するチューニング」を参照してください。

(3) FullGCの発生を抑止するチューニング

(a) FullGCの発生を抑止する考え方

FullGCの発生を抑止するチューニングの流れを次の図に示します。

図2‒32 FullGCの発生を抑止するチューニングの流れ

[図データ]

FullGCはTenured領域の使用サイズが増加し続け,Freeリージョンが確保できなくなった場合実行されます。

FullGCの発生を抑止するチューニングのイメージを次の図に示します。

図2‒33 FullGCの発生を抑止するチューニングのイメージ

[図データ]

FullGCの発生を抑止するには,Tenured領域の使用サイズの増加を防ぐ必要があります。そのため,FullGCの発生を抑止するには次の2つの方法が考えられます。

  1. Tenured領域へ移動するオブジェクト数を減らす

  2. Tenured領域内で不要なオブジェクトを回収する

Survivor領域あふれが発生している場合は1の方法で,発生していない場合は2の方法でチューニングしてください。1の方法の詳細については,「(c) Survivor領域のサイズチューニング」を,2の方法の詳細については,「(d) MixedGCで選択されるリージョンを増やすチューニング」を参照してください。チューニングをした場合,再度システムの検証をし,要件を満たしているか確認してください。

(b) サイズの大きなオブジェクトが多数作成されている場合

1つのオブジェクトのサイズが大きいオブジェクトが多数作成される場合,連続した領域が確保できないで,FullGCが実行される場合があります。G1GCではメモリをリージョンで管理しているため,オブジェクトのサイズが大きいオブジェクトが多数作成されるシステムには不向きです。オブジェクトのサイズが大きいオブジェクトが多数作成されることによって,FullGCが発生している場合は,アプリケーションの改修をしてください。

サイズの大きなオブジェクトはログの「Humongous」の項目から確認できます。

[VG1]<Wed Jan 15 12:51:32 2014>[Full GC 130443K/131072K(131072K)->55462K/56320K(131072K), 2.3265610 secs][Status:-][G1GC::Eden: 0K(43008K)->0K(43008K)][G1GC::Survivor: 0K->0K][G1GC::Tenured: 131072K->56320K][G1GC::Humongous: 1024K->0K][G1GC::Free: 0K->74752K][Metaspace: 3634K(4492K, 4492K)->3634K(4492K, 4492K)][class space: 356K(388K, 388K)->356K(388K, 388K)][cause:ObjAllocFail][RegionSize: 1024K][Target: 0.2000000 secs][Predicted: 0.0000000 secs][TargetTenured: 0K][Reclaimable: 0K(0.00%)][User: 2.1700000 secs][Sys: 0.0000000 secs][IM: 277185K, 261856K, 44544K][TC: 1168][DOE: 0K, 0][CCI: 5808K, 49152K, 5952K]

(c) Survivor領域のサイズチューニング

Tenured領域へ移動するオブジェクト数を減らす方法は,Survivor領域にオブジェクトが存在する間に,オブジェクトを回収する方法です。Survivor領域の空き領域がなくなると,本来寿命の短いオブジェクトがSurvivor領域あふれによる退避でTenured領域に昇格します。そのため,Survivor領域を大きくすることで,寿命の短いオブジェクトをSurvivor領域で回収し,Tenured領域への移動量を減らします。

ログに次のように「to exhausted」が出力されている場合,Survivor領域あふれが発生しています。この場合Survivor領域を大きくするために,-Xmxオプションまたは-XX:SurvivorRatioオプションでチューニングをしてください。

[VG1]<Wed Jun 12 11:21:10 2013>[Young GC 899070K/899072K(1048576K)->501755K/501760K(1048576K), 0.0931560 secs][Status:to exhausted][G1GC::Eden: 389120K(389120K)->0K(397312K)][G1GC::Survivor: 41984K->41984K][G1GC::Tenured: 459776K->459776K][G1GC::Humongous: 2048K->2048K][G1GC::Free: 609536K->607232K][Metaspace: 3634K(4492K, 4492K)->3634K(4492K, 4492K)][class space: 356K(388K, 388K)->356K(388K, 388K)][cause:G1EvacuationPause][RegionSize: 1024K][Target: 0.2000000 secs][Predicted: 0.2495800 secs][TargetTenured: 0K][Reclaimable: 0K(0.00%)][User: 0.0156250 secs][Sys: 0.0312500 secs][IM: 729K, 928K, 0K][TC: 509][DOE: 16K, 171][CCI: 2301K, 49152K, 2304K]

チューニングに用いるオプション名とチューニング方法を次に示します。

  • -Xmxオプション

    指定する値を大きくすることで,Javaヒープ領域のサイズが大きくなります。Javaヒープ領域全体のサイズが大きくなることで,Survivor領域のサイズも大きくなります。ただし,Javaヒープ領域の最大サイズを大きくすると,New領域がリサイズされる範囲の最小値と最大値が大きくなります。これによって最小停止時間が大きくなるため,チューニングをしたあとに再度システム要件を満たしているか検証してください。

  • -XX:SurvivorRatioオプション

    指定する値を小さくすることで,予約したNew領域のうち,Survivor領域に割り当てる割合を大きくします。ただし,この方法はEden領域がチューニング前に比べて小さくなるため,YoungGCやMixedGCが発生しやすくなる副作用があります。そのため,チューニングをしたあとに再度システム要件を満たしているか検証してください。

    重要

    Survivor領域を大きくする方法として-XX:NewRatioや-XX:NewSize,-XX:MaxNewSizeオプションを使ってNew領域のサイズを大きくする方法もあります。しかし,この場合GC後のNew領域のリサイズが制限されるため,New領域のサイズを変更するオプションの指定は推奨しません。

(d) MixedGCで選択されるリージョンを増やすチューニング

MixedGCで対象とするリージョンを増やすには,1度のMixedGCの対象リージョンを増やす方法と,MixedGCの発生頻度を上げて対象リージョン延べ数を増やす方法があります。1度のMixedGCの対象リージョン数を増やす方法はレスポンスが低下し,対象リージョンの延べ数を増やす方法はスループットが低下します。システム要件にあわせてチューニング方法を選択してください。

  • -XX:MaxGCPauseMillisオプション

    指定する値を大きくすることで,目標停止時間が大きくなります。MixedGCではNew領域とTenured領域の一部を対象としてGCをします。Tenured領域はNew領域を選択しても予測停止時間に対して目標停止時間に余裕がある場合に選択されます。そこで,目標停止時間を大きくすることで,1度のMixedGCで選択されるTenuredリージョンの数が増えます。ただし,この方法はGC停止時間が長くなるため,レスポンスが低下します。

  • -XX:ConcGCThreadsオプション

    指定する値を大きくすることで,CMをするスレッド数が増えます。MixedGCが実行されるためには,CMが終了している必要があります。そのため,CMをするスレッド数を増やし,CMの終了間隔を短くします。これによってMixedGCの発生回数が増え,MixedGCで選択されるリージョンの延べ数が増えます。ただし,この方法では,アプリケーションスレッドと並行して処理をするスレッド数が増えるため,スループットが低下します。

    また,CMスレッド数はEvacuationをするスレッド数より多い値を指定できません。そのため,-XX:ConcGCThreadsオプションとあわせて,-XX:ParallelGCThreadsオプションの値も大きくする必要があります。

(4) 最悪レスポンス時間を短くするチューニング

最悪レスポンス時間を短くするチューニングの流れを次の図に示します。

図2‒34 最悪レスポンス時間を短くするチューニングの流れ

[図データ]

このチューニングは,GCによるアプリケーションの停止時間を短くすることで,最悪レスポンス時間を短くする方法です。そのため,レスポンス時間のうち,GCによるアプリケーションの停止時間が占める割合が大きい場合に有用です。GCによるアプリケーションの停止時間は,VG1ログのgc_timeの項目から取得できます。

VG1ログの詳細については,「-XX:[+|-]HitachiVerboseGC(拡張verbosegc情報出力オプション)」を参照してください。

最悪レスポンス時間を短くするには,GCによるアプリケーションの停止時間を短くする必要があります。G1GCでは停止時間を指定することができるため,指定する値を小さくすることで最悪レスポンス時間を短くします。

[VG1]<Wed Jun 12 11:21:10 2013>[Young GC 899070K/899072K(1048576K)->501755K/501760K(1048576K), 0.0931560 secs][Status:-][G1GC::Eden: 389120K(389120K)->0K(397312K)][G1GC::Survivor: 41984K->41984K][G1GC::Tenured: 459776K->459776K][G1GC::Humongous: 2048K->2048K][G1GC::Free: 609536K->607232K][Metaspace: 3634K(4492K, 4492K)->3634K(4492K, 4492K)][class space: 356K(388K, 388K)->356K(388K, 388K)][cause:G1EvacuationPause][RegionSize: 1024K][Target: 0.2000000 secs][Predicted: 0.2495800 secs][TargetTenured: 0K][Reclaimable: 0K(0.00%)][User: 0.0156250 secs][Sys: 0.0312500 secs][IM: 729K, 928K, 0K][TC: 509][DOE: 16K, 171][CCI: 2301K, 49152K, 2304K]

目標時間を短くしてもGCの停止時間が短くなっていない場合は,最小停止時間に達しています。また,目標時間を最小停止時間に近づけ過ぎると,目標停止時間を超えたときの超え幅が大きくなり,最悪レスポンス時間が長くなる場合があります。目標停止時間を短くしてもシステム要件を満たせない場合は,チューニングではシステム要件を満たせません。その場合は,アプリケーションを改修してください。

(5) スループットを向上させるチューニング

スループットを向上させるチューニングの流れを次の図に示します。

図2‒35 スループットを向上させるチューニングの流れ

[図データ]

スループットを向上させるためには,GCの発生回数を減らす必要があります。YoungGCやMixedGCは割り当てられたEden領域を使い切ると発生します。そこで,New領域を大きくすることでEden領域を大きくし,GCの発生回数を減らします。New領域を大きくするためには,-Xmxオプションまたは-XX:GCMaxPauseMillisオプションを用いてチューニングをします。

スループットを向上させるチューニングをしてもスループットが向上しない場合は,New領域のサイズがリサイズされる範囲の最大サイズに達していることが考えられます。ログのEden領域+Survivor領域の値の変化からリサイズがされているか確認してください。ログの確認方法の詳細については,「2.3.1(8) YoungGC」を参照してください。なお,スループットを向上させるチューニングをするとレスポンスが低下する場合があるため,チューニング後は性能の再検証をする必要があります。