7.16.3 FullGCの発生を抑止するチューニング
- 〈この項の構成〉
(1) FullGCの発生を抑止する考え方
FullGCはTenured領域の使用サイズが増加し続け,Freeリージョンが確保できなくなった場合実行されます。
次にFullGCの発生を抑止するチューニングのイメージを示します。
FullGCの発生を抑止するには,Tenured領域の使用サイズの増加を防ぐ必要があります。そのため,FullGCの発生を抑止するには次の2つの方法が考えられます。
-
Tenured領域へ移動するオブジェクト数を減らす
-
Tenured領域内で不要なオブジェクトを回収する
Survivor領域あふれが発生している場合は,1の方法で,発生していない場合は2の方法でチューニングしてください。1の方法の詳細については,「7.16.3(3) Survivor領域のサイズチューニング」を,2の方法の詳細については,「7.16.3(4) MixedGCで選択されるリージョンを増やすチューニング」を参照してください。チューニングをした場合,再度システムの検証をし,要件を満たしているか確認してください。
(2) サイズの大きなオブジェクトが多数作成されている場合
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]
(3) 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領域のサイズを変更するオプションの指定は推奨しません。
(4) 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オプションの値も大きくする必要があります。