本連載は、現場でのエンジニアの経験から得られた、APサーバをベースとしたWebアプリ開発における注意点やノウハウについて解説するハック集である。現在起きているトラブルの解決や、今後の開発の参考として大いに活用していただきたい。(編集部)
それまで順調に動いていたはずのWebアプリケーションが、ある時突然、応答を返さなくなる。そして、運用者があたふたしている間に、何事もなかったかのように再び動き出す。
Javaで構築したシステムにかかわる者ならば誰しもが体験するであろう事象、そうFull GC(ガベージ・コレクション)だ。Full GCが行われている間、すべてのアプリケーションスレッドは停止する。この事象は“Stop the World”とも呼ばれている。
Full GCに対しては、世代別GCを適切にチューニングし、発生回数を減らす事で対処してきた。しかし、世代別GCのチューニングでは、Full GC1回当たりの停止時間を短くできない。サーバに搭載されるメモリが数Gbytesを超えるのが当たり前になってきた現在では、Javaに指定するHeapサイズも1Gbyteを超えるケースが出てきている。そのためHeapサイズの巨大化に伴い、Full GC時間が無視できなくなってきている。
本稿では、Full GC時間を改善するための手段となる「コンカレントGC」について解説する。
コンカレントGCの解説の前に、従来の世代別GCについて簡単に振り返っておこう。世代別GCは、Java VMのHeap領域をNew世代/Old世代に分け、オブジェクトの生存期間に応じてGCを効率化する。生成された後、すぐに不要となる短命オブジェクトをNew世代領域で回収し、比較的長い期間必要となる長命オブジェクトをOld世代領域で長期的に管理する。
例えば、Webアプリケーションでは、以下のようにオブジェクトを分類できるだろう。
New世代のGC(マイナーGC)には、高速なCopy方式のGCが使用される。一方、Full GCとも呼ばれるOld世代のGC(メジャーGC)にはMark-Sweep-Compact方式のGCが使用される。Mark-Sweep-Compact方式のGCは、その名のとおり、以下の流れで処理を行う。
メジャーGCはコストが高く、時間がかかってしまう。
これらのGCは、高速化のために複数のスレッドで実行することもでき、それらはパラレルGCと呼ばれている。しかし、いくら複数のスレッドでGCを実行しても、その間すべてのアプリケーションのスレッドは停止される。
編集部注:世代別GCについて詳しく知りたい読者は、連載:事例に学ぶWebシステム開発のワンポイントの第6回「APサーバからの応答がなくなった、なぜ? ―GCをチューニングしよう―」や、連載:チューニングのためのJavaVM講座の後編「ガベージコレクタの仕組みを理解する」をご参照ください。
本稿ではコンカレントGCと区別するために、従来の世代別GCを「スループットGC」と呼ぶ。
コンカレントGCはJ2SE 1.4から使用できるGC方式で、Old世代のGCをアプリケーションスレッドと並列に実行する。
しかし、GCのアルゴリズム上、すべてのアプリケーションスレッドを停止する必要のある期間がどうしても存在する。コンカレントGCでは、GCを次の4つのフェイズに分割して処理することで、その期間を最小化している。
このような仕組みにより、コンカレントGCでは“Stop the World”を回避している。
一見良いことずくめのように思えるコンカレントGCだが、問題点もある。コンカレントGC実行中はGCスレッドが動作している分、負荷が高くなる。そのため、全体的なスループット(ある単位時間当たりの処理能力)は下がり、応答時間も遅くなるのだ。
どれくらい性能が劣化するかについては、アプリケーションの作り方や、システムに対する負荷状況により異なる。筆者の経験では、コンカレントGCの高負荷時の性能がスループットGCと比較し、30%程度低下したこともあった。このような大幅な性能劣化があると、コンカレントGCの採用を見送らざるを得ない。
コンカレントGCはなぜここまで性能が劣化してしまうのだろうか。実はコンカレントGCでは、New世代領域に関連するオプションのデフォルト値として「-XX:SurvivorRatio=1024 -XX:MaxTenuringThreshold=0」という値が設定される(オプションの意味については、後述)。そのため、1回のマイナーGCで回収されなかった短命オブジェクトはすぐにOld世代領域に移動してしまう。結果として、Old世代領域の使用量が上がりやすくなり、メジャーGCの回数が増えてしまうのだ。
この問題を解決するための手段として、コンカレントGCと世代別GCを組み合わせて使用することが可能だ。以降では、マイナーGCを活用したコンカレントGCのためのチューニングについて見ていこう。
Copyright © ITmedia, Inc. All Rights Reserved.