Full GCの発生は、ミッションクリティカルなWebシステムでは許容できない問題である。発生の抑止方法について順を追って検討してみよう。
Webシステムの安定動作には、メモリ使用量の適切な見積もりが不可欠であることをは前回に説明した。しかしJavaの特性上、しっかりとサイジングしてもある程度のFull GCの発生は避けられない。Full GC実行中には、Webシステムが一時停止して応答がない「Stop the World」と呼ばれる現象が発生する。これはミッションクリティカルなシステムでは許容することができない問題である。その原因と対策方法を、改めて紹介する。
一般にGCでは、不要になったメモリ域の破棄と同時に、メモリ域の再編成(コンパクション)が実行される。これによってメモリ域の断片化(フラグメンテーション)を防ぎ、連続したメモリを確保できるようにする。ただし、このメモリ再編成処理の間は、業務プログラムを動作させられない。つまり利用者からは、GCの処理中は業務システムが一時的に停止したように見えるのである。この現象が「Stop the World」と呼ばれるもので、Javaベースの業務システムでは頭の痛い現象となっている。
Full GCの場合、特に問題となるのは業務システムの停止時間の長さだ。GCの対象となるメモリ域の範囲は、Copy GCよりFull GCの方が広いため、一般にFull GCの方が停止時間は長くなる。GCに要する時間はメモリサイズによって異なるが、アプリケーションサーバのように500Mバイトから1Gバイト近くのメモリサイズを使用する場合、Copy GCは0.01秒から0.7秒程度と1秒に満たない間に終了するのに対し、同じ条件でFull GCが発生した場合1秒から数10秒とされている。Javaヒープ領域が大きい場合には、30秒以上掛かることも珍しくない。以下に、Copy GCとFull GCの違いを表で示す。
GCの種類 | GC実行の契機 | GC実行の範囲 | 実行時間 |
---|---|---|---|
Copy GC | Javaヒープ領域のEden領域があふれると発生 | New領域 | 0.01〜0.7秒 |
Full GC | Javaヒープ領域のOld領域があふれると発生 | Javaヒープ領域全体 | 1秒〜数10秒 |
現在はコンピュータシステムの64ビット化が加速し、メモリの増量も進んでいる。Full GCを防ぐだけなら、メモリ域を拡張すればよい。だがメモリ域を拡張すると、1回当たりのFull GCに要する時間も増加してしまう。結果として、システムの停止時間を短くすることはできないのである。
基本的にJavaで開発した業務システムは、Full GCの発生による業務システム停止を避けることは非常に難しい。そのため以降の対策を参考にして、業務システムのサービスレベルに応じたFull GCによるStop the Worldに影響されないシステム構築を行う必要がある。
Copyright © ITmedia, Inc. All Rights Reserved.