はじめに

こんにちは。
キャスレーコンサルティング IT(インテグレーションテック)部の鈴木(郁)です。

突然ですが、GCとは何かご存じでしょうか?

打ち合わせや障害発生時等どこかで耳にしたことがある方もいらっしゃるかもしれません。

しかし、実際にGCが何をしているか知らないという方もいるかと思います。

私もその一人です。そのため、GCとは何かを調べてみました。
今回はその紹介となります。

目次

1.GC(ガベージコレクション)とは
2.Scavenge GCとFull GC
3.GCログの見方
4.Full GC (System.gc())について

1.GC(ガベージコレクション)とは

GC(ガベージコレクション)

GCとはプログラムが確保したメモリ領域のうち、
不要かどうか自動で管理し、不要になったものだけを解放してくれる機能のことです。

そのためプログラマがメモリ管理のためのコードを書かなくてもよくなり、
不要なメモリを解放し忘れるということが起こらなくなります。

2.Scavenge GCとFull GC

ガベージコレクションには、大きくわけて
“Scavenge GC(スキャベンジ・ジーシー)”
“Full GC(フル・ジーシー)”
の2種類があります。

Scavenge GC

まず、ヒープ領域にはNew領域とOld領域があります。

 New領域:生成された新しいオブジェクトまたは寿命の短いオブジェクトが入る

 Old領域: Scavenge GCによってNew領域より移動されたもっと長い寿命を持つオブジェクトが入る

New領域の中には、「Eden領域」と「Survivor領域」という領域があります。

「Eden領域」には新規に生成されたオブジェクトが入り、
「Survivor領域」にはEden領域に格納された後、
Scavenge GCが実行されてもまだ使用されているオブジェクト(参照されているオブジェクト)が入ります。

Scavenge GCは、ヒープ領域のうちNew領域のみを対象としたものです。

これはEden領域がいっぱいになったときに実行されます。

Eden領域にあるオブジェクトのうち、不要になったオブジェクトはそのまま破棄され、
まだ使用されているオブジェクトをSurvivor領域(この図でいうと「Survivor 1」)に移動させます。

そして、再びEden領域がいっぱいになった際にScavenge GCが実行されたときは、
Eden領域とSurvivor領域内の不要オブジェクトが破棄され、まだ使用されているオブジェクトは
次のSurvivor領域(この図でいうと「Survivor 2」)に移動されます。

Survivor領域内でいききすることでEden領域に空きを作りますが、
Survivor領域にて移動回数が閾値を上回ったオブジェクトはold領域に移動されます。

Eden領域がいっぱいになる度に、実行されるため頻度は多いですが
処理時間は短時間で終わります。

Full GC

Full GCは、ヒープ領域全体を対象にしたものです。

これは、old領域がいっぱいになったときに実行されるます。

そのため頻度はScavenge GCほど高くありませんが、
New領域とOld領域両方を対象にしているため処理に時間がかかります。

Full GCの影響

GCでは不要になったメモリ領域の解放と、メモリ領域の再編成(コンパクション)が行われます。

しかし、このメモリ再編成の間は
アプリケーションからのリクエスト等の処理を実行することが出来ません。

そのためユーザからは、システムが停止してしまっているように見えます。
この状態のことを”Stop the World”といいます。

3.GCログの見方

Scavenge GCログ

Scavenge GCログでは、New領域GCの閾値から解放された領域を確認します。

Full GCログ

Full GCログではヒープ全体から解放された領域を確認します。
また、realにて処理時間を確認することも大切です。

4.Full GC (System.gc())について

GC には、Allocation FailureとSystem.gc()があります。

Allocation Failure:
 領域内で新規オブジェクトを作成するために、必要な空き領域が足りなくなったため実行
System.gc():
 GCの強制的呼び出し

System.gc()は、プログラムの中で強制的にGCを行いたいときに使用する
java.lang.Systemクラスのgcメソッドです。

これは、明示的にプログラムに入れない限り実行されないものです。

Allocation FailureとSystem.gc()で開放されるメモリに違いはなく、
System.gc()を繰り返したからといって、
必ずしも使用可能なメモリ領域が確保できるというわけではありません。

また、指定されているプログラムが動くたびにFull GC が実行されるため
何度も続いてしまうと ”Stop the World”の状況が長く続く続いてしまいます。

使用する際は本当に必要か、システムに影響はないかしっかり確認してください。

終わりに

いかがでしたでしょうか。

今回調べてみて、GCとはプログラムが動くのにとても重要な役割をしていることがわかりました。

GCによる障害もあるため、これからGCについても意識していただけると
よりよいサービスを提供できるようになると思います。

最後までお読みいただき、ありがとうございました。

鈴木(郁)
CSVIT事業部 IT(インテグレーションテック)部 鈴木(郁)
現在はミドルウェアの運用保守を行っています。