Javaパフォーマンスを読んでる。
自分なりに理解した内容をメモる。
5章:ガーベージコレクションの基礎
ガーベージコレクション概要
定期的にヒープを走査して参照されていないオブジェクトを開放する。
断片化解消のため、メモリの配置し直しをする。
これを実行しているとき、Javaアプリケーションの処理は停止する。
Young領域とかOld領域とか
Young領域やOld領域をヒープ内にもっていて、定期的にGCを実行して使用中オブジェクトを整理している。
新規オブジェクトはYoung領域に確保され、そこが一杯になると軽量のGCが発生する。(young領域はヒープの一部分なのでGCにかかる時間が短い)
YoungGCはスレッド停止(アプリケーション停止)を伴い、未使用オブジェクトを開放し、使用中オブジェクトをOld領域やSurvivor領域に移動させる。
こうすることで、メモリ開放と断片化解消を行う。
YoungGCがたくさん実行され、次第にOld領域が一杯になるとFullGCが実行される。
FullGCはヒープ全体に対してのGCなのでYoungGCに比べて時間がかかる。そのためスレッド停止時間も長い。
パフォーマンス・チューニングの基本戦略としては「なるべくYoungGCのみでFullGCは起こさないようにする」になる。
もちろんアプリケーションがどのように使われるかによる部分であり、定期的に処理が遅くなる(FullGCによる長時間スレッド停止)が許容できるならFullGCを頻発させるほうが全体のパフォーマンスとしては良い、というのもありえる。
GCのアルゴリズム
GCには複数のアルゴリズムがあり、上記の説明どおりのアルゴリズムから、なるべくFullGCを起こさないようにするアルゴリズムもある。
たとえばG1アルゴリズムはヒープを複数の領域に分けて管理することで一つ一つの領域のGCによる処理停止時間を短くしたり、GC処理の一部はメインスレッドと並列で走らせるなどしてアプリケーションの停止をなるべく引き起こさないようにしたりしている。
ただし、どのアルゴリズムでもOld領域がいっぱいになればやはりFullGCは発生する。
パフォーマンスチューニング
ガーベージコレクションのチューニングによるパフォーマンスチューニングとは、
- どの程度のスレッド停止が許容されるのか?
- まとめて長時間停止で回数を少なくしたほうがいいのか?
- こまめに短時間停止で回数を多くしたほうがいいのか?
このあたりを見極めてヒープの領域配分やしきい値調整をすることであると理解した。