NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

JavaのGCの仕組みを整理する
https://qiita.com/e_tyubo/items/48398391a8ef0f24c1be

ヒープ領域のYoung領域は下図のようにEdenとSurvivorに分かれており、それぞれの領域を上手く使ってGCが行われます。

それぞれの領域はざっくり下記の役割を持っています。
* Eden最初に割り当てられるメモリ領域
* Survivor1, Survivor2GC後に解放されず、かつOldには行かないデータ(便宜的に2種類あるものに1と2をつけてるだけです)
* TenuredOldのこと。指定回数GCを経験して生き残ったデータOldに移行される

マイナーGC
Young世代だけを対象としたGCのことをマイナーGCと言います。下記の特徴があります。
* 処理時間が短い
* Edenがいっぱいになったら発生
* 特定回数GC対象になるとOldに移動(昇格)する
* GCの間プロセスの処理は停止(Stop the world)

参照がないデータは削除されますが、有効なデータはSurvivor領域にコピーされます。また、Eden領域は全て空になります。

さらにこの状態でまたEdenがいっぱいになったら再度マイナーGCが発生して下図のようになります。

今回は GC後に全てSurvivor2に入りました。Survivor領域はどちらか空いてる方にデータをコピーされて、1と2を行き来することになります。
また、Edenと同様にSuvivor領域からも参照されないデータは削除されます。
次にOldへの昇格です。GCが発生するたびにYoungのデータはその回数が記録され、一定回数を超えたらOldに移動します。

この様に何度もGCを繰り返すことで、YoungからOldへの移動が発生します。この回数はオプションで指定することができるため、Oldへ行く頻度を制御することができます。
-XX:MaxTenuringThreshold=N

FullGC
YoungからOldにデータが移る仕組みはわかりましたが、これだけだとOldの容量が常に増え続けることになり、どこかで容量の限界がきます。そこでFullGCの出番です。Oldに割り当てが失敗したタイミングでFullGCが発生し、OldとYoungを両方含めてメモリを掃除します。

これによりOld領域で不要となった空間が解放され、Survivor領域にいたデータをコピーすることができます。



マイナーGCと同様にFullGC中もアプリケーションは停止してしまいます。しかもOldが入ってる分停止時間も長いため、メモリは極力Young領域で解放される使い方をして発生を抑えることが大事になりそうです。

まとめると
* Eden領域がいっぱいになるとマイナーGCが発生
* マイナーGCによってYoung領域を解放し、条件を満たせばOldに昇格
* Old領域がいっぱいになるとFullGCが発生
* FullGCでOld領域を解放し昇格できるスペースを確保
というサイクルであることがわかりました。

今ではデフォルトで選択されるGCのアルゴリズムがG1GCだったりするので、次はそれについてまとめてみようと思います。


3分で理解するG1ガベージコレクション
https://qiita.com/tshk_mtsys/items/5a027fe00b3bff009b17


GC戦略
https://www.google.com/amp/s/blog1.mammb.com/entry/2018/03/13/202231%3Famp%3D1

GC戦略はアプリケーションの要件と照らして適切なものを選択する必要がある。
フラグ 説明
-XX:+UseSerialGC シリアル型GC。マイナーGC、フルGCの両方がアプリケーションを停止して処理される
-XX:+UseParallelGC -XX:+UseParallelOldGC パラレル型GC。young領域とold領域のGCに複数スレッドが利用される。マイナーGC、フルGCの両方でアプリケーションスレッドは停止

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC CMS型GC。マイナーGCではアプリケーションスレッドを停止し、複数スレッドで処理。old領域はアプリケーションスレッドと並行でGCが行われる
-XX:+UseG1GC CMS型GCを複数のリージョンに分割したヒープ上で行う。CMS型GCに比べてold領域の断片化が発生しにくい
* • シリアルGC
* 最もシンプルなGC
* 単一CPUの32bitプラットフォームのデフォルト
* GC処理は常にアプリケーションスレッドが停止
* 小さなヒープ(100M程度)の場合の選択肢
* パラレルGC
* GC処理は常にアプリケーションスレッドが停止
* マイナーGCを複数スレッドで処理
* -XX:+UseParallelOldGC フラグによりフルGCも複数スレッドで処理
* GCによる長いストップ・ザ・ワールドが許容でき、スループットを最大化する場合の選択肢
* CMSGC
* マイナーGC時にはアプリケーションスレッドが停止
* マイナーGCは複数スレッドで処理(-XX:+UseParNewGCのアルゴリズム利用)
* old領域のGC時にはアプリケーションスレッドが停止しない
* バックグラウンドスレッドにより並列で未使用オブジェクトを破棄
* old領域が断片化が進行した場合、アプリケーションスレッドを停止してクリーンアップとコンパクト化を単一スレッドで実施
* 同種の -XX:+CMSIncrementalMode(細かい単位でGCを行う) は今では推奨されていない
* G1GC
* マイナーGC時にはアプリケーションスレッドが停止
* マイナーGCは複数スレッドで処理
* old領域のGC時にはアプリケーションスレッドが停止しない
* バックグラウンドスレッドにより並列で未使用オブジェクトを破棄
* ヒープはリージョンに分割されており、断片化が発生しにくい
* 大きなヒープ(4G以上)でアプリケーションの停止を望まず、CPUに余裕のある場合の選択肢


GCログ
GCログは商用利用であれば必ず設定しておきたい。
フラグ 説明
-verbose:gc GCログを出力
-Xloggc:<パス> GCログをファイル出力 Java8からは gc_%p_%t.log のようにすると、%pにPID, %tに日時が入ったファイルが作成できる
-XX:+PrintGCDetails GCの詳細出力
-XX:+PrintGCDateStamps GCログに日時出力する。-XX:+PrintGCTimeStamps だと相対時間となり見にくい
-XX:+PrintGCApplicationStoppedTime Stop The World した時間を出



JVMのヒープサイズとコンテナ時代のチューニング
https://i-beam.org/2019/08/15/jvm-heap-sizing/

UseContainerSupportはCGroupからメモリ制限を取得するだけでなく、次の機能もあります。
* CGroupのCPUの制限値も使用する
* CGropu上のメモリの利用率も取得できる
UseContainerSupportオプションはデフォルトで有効になっています。 そのため特に何も指定しなくても、コンテナが利用できるメモリ容量の1/4がヒープサイズとして割り当てられます。

MaxRAMPercentageは-XX:MaxRAMPercentageオプションで指定できます。 次の例はMaxRAMPercentage=75を指定してます。 CGroupのメモリサイズが1024MBなので、75%までの768MBをヒープ領域として利用できます。





Java Platform, Standard Edition HotSpot Virtual Machineガベージ・コレクション・チューニング・ガイド
https://docs.oracle.com/javase/jp/8/docs/technotes/guides/vm/gctuning/sizing.html

デフォルトで、若い世代のサイズはパラメータ‪NewRatio‬で制御します。たとえば、‪-XX:NewRatio=3‬と設定すると、若い世代とTenured世代の比率が1:3になります。つまり、Eden領域とSurvivor領域の合計サイズが、合計ヒープ・サイズの1/4になります。


表4-2 Survivor領域のサイズ設定のデフォルト・パラメータ値
パラメータ サーバーJVMのデフォルト値
‪NewRatio‬ ‪2‬
‪SurvivorRatio‬ ‪8‬
若い世代の最大サイズは、ヒープ総量の最大サイズと‪NewRatio‬パラメータの値から計算されます。


GC関連のオプション
http://namihira.hatenablog.com/entry/20151223/1450833525


JVMアプリケーションを運用する際のメジャーどころチューニングポイントメモ
https://yoskhdia.hatenablog.com/entry/2017/11/05/224428


表10-1 G1ガベージ・コレクタの重要なオプションのデフォルト値
https://docs.oracle.com/javase/jp/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#default_g1_gc

‪-XX:G1HeapRegionSize=n‬ ‪G1リージョンのサイズを設定します。この値は2の累乗で、1MBから32MBの範囲で指定できます。最小Javaヒープ・サイズを基に、リージョンが約2048個になるようにします。‬
‪-XX:MaxGCPauseMillis=200‬ ‪望ましい最大一時停止時間の目標値を設定します。デフォルト値は200ミリ秒です。指定された値はヒープ・サイズには適応されません。‬

‪-XX:G1NewSizePercent=5‬ ‪若い世代の最小サイズとして使用するヒープの割合を設定します。デフォルト値は現在のJavaヒープの5%です。脚注1‬
‪これは試験的なフラグです。「試験的なVMフラグのロック解除方法」で例を参照してください。この設定は-XX:DefaultMinNewGenPercent設定にかわるものです。‬
‪-XX:G1MaxNewSizePercent=60‬ ‪若い世代の最大サイズとして使用するヒープ・サイズの割合を設定します。デフォルト値は現在のJavaヒープの60%です。脚注1‬
‪これは試験的なフラグです。「試験的なVMフラグのロック解除方法」で例を参照してください。この設定は-XX:DefaultMaxNewGenPercent設定にかわるものです。‬
‪-XX:ConcGCThreads=n‬ ‪パラレル・マーキング・スレッド数を設定します。nをパラレル・ガベージ・コレクション・スレッド(ParallelGCThreads)の数の約1/4に設定します。‬
‪-XX:InitiatingHeapOccupancyPercent=45‬ ‪マーキング・サイクルを開始するJavaヒープ占有率のしきい値を設定します。デフォルトの占有率はJavaヒープ全体の45%です。‬
‪-XX:G1MixedGCLiveThresholdPercent=85‬ ‪混合ガベージ・コレクション・サイクルに含める古い世代の占有率のしきい値を設定します。デフォルトの占有率は85%です。脚注1‬
‪これは試験的なフラグです。「試験的なVMフラグのロック解除方法」で例を参照してください。この設定は-XX:G1OldCSetRegionLiveThresholdPercent設定にかわるものです。‬
‪-XX:G1HeapWastePercent=5‬ ‪未使用にするヒープの許容割合を設定します。再生可能な割合がヒープの未使用率を下回ると、Java HotSpot VMは混合ガベージ・コレクション・サイクルを開始しません。デフォルトは5%です。脚注1‬
‪-XX:G1MixedGCCountTarget=8‬ ‪マーキング・サイクル後に古いリージョンのライブ・データ(最大でG1MixedGCLIveThresholdPercent%)を収集する混合ガベージ・コレクションの目標回数を設定します。デフォルトは、8回の混合ガベージ・コレクションです。混合コレクションの実行を、この目標回数以内に抑えます。脚注1‬

‪-XX:G1OldCSetRegionThresholdPercent=10‬ ‪混合ガベージ・コレクション・サイクル時に収集する古い世代の数に上限を設定します。デフォルトはJavaヒープの10%です。脚注1‬
脚注1この設定はJava HotSpot VMビルド23以前では使用できません。


★★★デフォルト設定でのサイズ概算★★★
・コンテナが利用できるメモリ容量:2048MB
・1/4がヒープサイズ:512MB

・ヒープの1/3 New領域:170MB
8 Eden:126MB
→一杯になるとマイナーGC発生
‪ 1 Survivor1:21MB‬
‪ 1 Survivor2:21MB‬

・ヒープの2/3 Old領域(=Tenured)340MB
→一杯になるとfullGC or CGC発生
しきい値設定:6?8?
→MaxTenuringThresholdオプションで変更可能
fullGC or CGC発生条件の設定?(Old領域の残領域の割合)
→‪G1MixedGCLiveThresholdPercent=85‬







★Jackson でハイパフォーマンスな JSON 処理をするためのベストプラクティス (1)
https://qiita.com/komiya_atsushi/items/803f69b51426ed476a75






★調査手順
・ローカルeclipseの実行構成で、SpringアプリケーションのJVM起動引数に以下を設定。
 (ヒープサイズ等は調査目的によって要調整。前述の参考サイト情報のうち、使用できないオプションもいくつかあったので、使えたものに絞っている。)
JVM
-verbose:gc
-XX:+PrintGCDetails
-Xloggc:C:/#work/gclog/gc.log
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=C:/#work/gclog/heapdump/
-XX:MaxHeapSize=512m


・監視ツール起動
jconsole(GUI)

・連続リクエスト
jmeter使用
20スレッド、10req/seq程度の負荷で無限ループ
→必要に応じてjmx設定を調整

※以降、GitBash上で実行
・JavaプロセスID取得コマンド
jps -v | less -SN
18904

・GC/ヒープ状況監視コマンド
(ファイル出力しておき、必要ならtailで監視)
※日時出力オプションを付けた方が良いかも

jstat -gcutil -h10 18904 1000 > jstat.log
tail -f jstat.log

・heatdump取得(jmap)
(手動実行)
jmap -dump:format=b,file=./heapdump_$(date "+%Y%m%d_%H%M%S").hprof 18904
→FullGCを発生させずに、ダンプ取得

jmap -dump:live,format=b,file=./heapdump_live_$(date "+%Y%m%d_%H%M%S").hprof 18904
→FullGCを発生させてから、ダンプ取得(生存オブジェクトが残るか確認したい場合)

(定期的に取得したい場合)  ※.bash_profileに追加した独自定義コマンド
repeat_jmap 18904

repeat_jmap_live 18904


■結果分析

・jconsole
→目視。ヒープ、その他情報の確認

・jstat.log
→目視。のGC・ヒープ状況確認

・アプリ出力のgc.log
→gcViewer

・MemoryAnalyzer
→heatdumpの解析

・jstack
→スレッド、スタック確認(今回は不要)



■ツール利用方法参考
Java開発の性能改善! その1 jstatによるヒープ/GCの確認
https://qiita.com/i_matsui/items/4997ebedbdd7a6495509

Java開発の性能改善! その2 GCログの解析とHeapの設定
https://qiita.com/i_matsui/items/aabbdaa169c6ae51ecb3

★Java開発の性能改善! その3 ヒープダンプを取ろう
https://qiita.com/i_matsui/items/0d1ae2c7e9d17b6c04e0

★メモリリークトラブルシューティング記 – その5: Memory Analyzer でヒープダンプを解析(最終回)
https://yusuke.blog/2008/11/10/999

★最強のJVMチューニング・ツール: GCログを可視化するGCViewerとリモート接続でプロファイリング可能なVisualVM
https://x1.inkenkun.com/archives/780




     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.