LoginSignup
71
63

More than 1 year has passed since last update.

Java VMのガーベジコレクションの整理

Last updated at Posted at 2014-02-08

Java VMのGC

Java VMには様々な種類のGC(ガーベジコレクション)があり、用語を整理しないと混乱します。

GCの種類を整理する前に、まずJava VMのGCは「世代別GC方式」を採っていることを意識しましょう。
Java 7で正式サポートが始まったG1 GCも、世代別GC方式がベースになっています。

「世代別GC方式」の詳細は、様々なWebサイトで紹介されているので、ここではポイントだけを記述します。

世代別GC方式とは

Java VMはJavaヒープを、
「New領域(1個)」「Tenured領域(1個)」と「Permanent領域(1個)」に分割し、
さらに「New領域」を「Eden領域(1個)」と「Survivor領域(2個)」に分割します。

生成されたオブジェクトはまずEden領域に入り、最初の数回の「コピーGC」によって2個のSurvivor領域の間を行き来します。それでも生存し続けたら、最後にTenured領域に昇華されます。
Permanent領域には、主にクラス情報が入ります。

このようにメモリ領域をいくつかの領域に分け、各領域に応じて異なる種類のGCを実行する方式が、「世代別GC方式」です。

2個あるSurvivor領域は常に片方が空き領域になっていて、この意味でメモリ容量を余分に消費しますが、コピーGCは効率的なGCです。

Tenured領域はGCを繰り返すと断片化がひどくなり、大きなオブジェクトを割り当てられなくなる場合があります。このようなときは、オブジェクトを一か所に集めて断片化を解消するための「コンパクション」を行います。

Tenured領域を対象としたGCには、FullGCとCMS GCの2種類があり、前者はコンパクションを兼ねますが、Stop the world(アプリケーションが完全に止まる)が起きます。後者はStop the worldを起こしませんが、コンパクションを行いません。また、FullGCでは、Tenured領域に限らずPermanent領域もCGの対象となります。

Java VMオプションでCMS GCを選択した場合、CMS GCを実行してもTenured領域とPermanent領域にオブジェクトを割り当てられない場合、フォールバックとして、コンパクションを行うために自動的にFullGCが実行されます。

用語の整理

世代別GC:
Java VMが採用している全体的なGC方式。

コピーGC:
New領域を対象とした効率的なGC。
Java VMオプションで単一スレッドで実行するか、複数スレッドで実行するかを選択可能。

FullGC:
Tenured領域とPermanent領域を対象としたGCであり、アプリケーションの動作を完全に止めてしまう。
コンパクションも行う。

CMS GC:
Tenured領域を対象としたGC。Stop the worldを回避するために、アプリケーションスレッドと同時に実行。
CMS GCを実行してもTenured領域とPermanent領域にオブジェクトを割り当てられない場合、フォールバックとしてFullGCを実行してコンパクションを行う。

G1 GC:
Java VMで正式サポートが開始された、64ビットの広大なメモリ空間を対象としたGC。
Javaヒープを細かく分割して、同じサイズの小さな領域をたくさん作り、Eden領域、Survivor領域またはTenured世代のどれかにする。

Java 7でのGCの選択

拙者ブログのJava™ 7でのガーベジコレクションの選択を参照してください。

71
63
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
71
63