GC、ヒープ、メモリ管理
JavaのHotspotVMのGCについて調べていたからちょっと書く。
領域について
- "ヒープメモリ" = "New領域(以下New)" + "Old領域(以下Old)"
- "New" = "ヒープメモリ" - "Old"
- "Old" = "ヒープメモリ" - "New"
- "New" = "Eden領域(以下Eden)" + "To領域(以下To)" + "From領域(以下From)"
- Edenというのは新しいオブジェクトが生成(Javaでいうところのnew)されたらそれを配置する場所。
- To, FromはEdenからオブジェクトが移動してくる。
- "To" = "From"
- "Survivor" = "To" + "From"
領域に関するパラメータ
- -XX:SurvivorRatio = "Eden / To(またはFrom)"
- -XX:MaxTenuringThreshold = N
- これにより指定された回数(N)ToとFromを行き来したオブジェクトはOldにコピーされる。
GCの種類
- Scavange GC(スキャベンジと読む。ゴミ箱あさりって意味らしい。)
こいつはNewを片付ける。
- Full GC
こいつはNew & Oldを片付ける。
GCのアルゴリズム
- Parallel Young Generation Collector
- デフォルト。
Newをマルチスレッドでコレクトする。
- Parallel Old Generation Collector
- Oldもマルチスレッドでコレクトする。
- Mostly Concurrent Mark-Sweep Collector
- FullGCの時間を短くするために
発動タイミングについて
- Edenがいっぱいだーーー!⇒Scavange
これによりEden→ToまたはFromへインスタンスが移動。
Scavangeが起こるたびにToとFromを行ったり来たりする。
- Oldがいっぱいだーーーー!⇒Full
観察
- jstatコマンド。
- "-gcutil", "-gcnew", "gcnewcapacity"などオプションを変えることでいろんな角度からヒープを観察できる。
エルゴノミクス
- Hotspotがマシンスペックを材料に、動的にSurvivorやEdenをself-sizingする。見た感じToで調節している?
ログについて
-XX:+PrintGCDetails -Xloggc:出力先パス
で出力される。
経過時間: [GC種, [領域識別名 : before -> after (領域の大きさ)], ..., 所要時間 secs]
チューニングの目標とは、サービスをより早く動かすことです。
と言うことは、どうしても時間のかかるFullGCを短くしなければならない。
しかし一方で、マシンのスペックをあげてメモリを割り当てれば割り当てるほどチューニングしなければFullGCの時間が長くなってしまう。