2:GC実行時の、GCスレッドとアプリケーション・スレッド
次に、「GC実施時の、GCスレッドとアプリケーション・スレッド」という視点で説明をいたします。この視点では、IBM JVMは以下の2つの方式を提供しています。
- Parallel Collector
- Concurrent Collector
これらを解説する前に、GCがパフォーマンスに及ぼす影響について説明しておきます。
そもそもGCとは? “Stop The World”とは?
そもそもGCは、オブジェクトのヒープ領域への割り当てが失敗した際に、発生します。そして、GC処理が開始されると、GC処理を担当するスレッド以外のスレッドは一時停止されます。それは、GC処理においてオブジェクトの移動やリファレンスの走査などを行うため、アプリケーション処理がGCと並行されることによるメモリ情報の整合性などの問題発生を防ぐためです。
GC処理開始から終了までの間、GC処理スレッド以外のスレッドが「一時停止状態」になるため、一般に、これを“Stop The World”と呼んでいます。
GC処理時間の短縮を期待:Parallel Collector
Parallel Collectorは、GC処理をマルチ・スレッドで実施するため、GC処理時間の短縮が期待できます。CPU数の多い大規模システムで効果的であるといえます。ただし、GC処理の間は、アプリケーション・スレッドは停止されます(“Stop The World”)。
アプリケーション・スレッドの停止時間の短縮を期待:Concurrent Collector
Concurrent Collectorを使用すると、GC処理の中のMark処理およびSweep処理をアプリケーション・スレッドと並行して実施できます。これにより、アプリケーション・スレッドの停止時間を短縮することが期待できます。
Concurrent Collectorは、GC処理を3つのフェイズに分類しています。
Concurrent Collectorのフェイズのフェイズ
まず、Concurrent Mark処理では、Live Object検出のための出発点となるルートセットをマークし、さらに、ルートセットからたどれるオブジェクト(Live Object)をマークします。この処理は、アプリケーション・スレッドと並行して処理されます。その後、アプリケーション・スレッドを停止して、Mark/Sweep/Compact処理が行われます。
Concurrent Mark処理中は、アプリケーション・スレッドも稼働しているため、Concurrent Mark処理でマークしたオブジェクトが参照されなくなったり、マークしたオブジェクトに対して、新しいオブジェクト参照が追加されたり(マーク漏れ)、といった状況が発生する可能性があります。そういった状況に対して、整合性を取るための処理が行われます。この処理の間、アプリケーション・スレッドは停止させられます。
Concurrent Sweep処理では、アプリケーション・スレッドと並行して、Dead Objectを回収し、空き領域を確保します。
Concurrent Collectorを使用すると、アプリケーション・スレッドの停止時間の短縮が期待できますが、Concurrent Mark処理がアプリケーション・スレッドと並行して稼働しているために負荷が高くなり、スループットに影響を及ぼす可能性があります。
3:分割(Generational)ヒープ領域 VS フラット・ヒープ領域
WAS 6.1のIBM JVMは、以前のWASのIBM JVMでサポートしていたヒープ・メモリのフラットなモデルに加えて、新たに“Generational GC”と呼ばれる仕組みを提供しました。Generational GCは、「オブジェクトの多くは短命である」という前提の下に最適化されております。
Nursery SpaceとTenured Space
Generational GCは、JVMヒープ領域をNew Area(「Nursery Space」とも呼ばれます)とOld Area(「Tenured Space」とも呼ばれます)と呼ばれる2つのエリアに分割します。
オブジェクトは、New Areaに作成され、そのオブジェクトが長期間存在した場合に、それら寿命の長いオブジェクトはOld Areaに移動/昇格(promote)します。オブジェクトが“tenure age”と呼ばれる、ある年齢に達した際に、オブジェクトが“promote”します。この年齢というのは、オブジェクトがNew Areaに存在している間に発生したGCの回数です。
Allocate SpaceとSurvivor Space
New Areaは、さらに“Allocate Space”と“Survivor Space”と呼ばれる2つの領域に分割されます。新しいオブジェクトは、New Areaの中の“Allocate Space”に作成されます。
Generational GCの動き
Allocate Spaceがいっぱいになると、“scavenge”と呼ばれるGC処理が実行されます。この“scavenge”処理によって、Live Objectは“Allocate Space”から“Survivor Space”へとコピーされます。
ただし、Live Objectが“tenure age”に達していた場合には、“Allocate Space”から“Tenured Space”へとコピーされます。Dead Objectはそのまま“Allocate Space”に残ります。そして、“Survivor Space”あるいは“Tenured Space”へすべてのLive Objectのコピーが完了した時点で、“Allocate Space”と“Survivor Space”の役割が入れ替わります。
つまり、その時点で、新しい“Survivor Space”には、Live Objectはまったく存在していない状態になり、Dead Objectも削除されます。
確認ですが、ここまでで以下の内容について理解できたと思います。
- ヒープ領域確保の方法
- Mark&Sweep GC
- Copying GC
- GC実行時の、GCスレッドとアプリケーション・スレッド
- Parallel Collector
- Concurrent Collector
- 分割ヒープ領域 VS フラット・ヒープ領域
Copyright © ITmedia, Inc. All Rights Reserved.