■ はじめに
初めにGarbageCollectionとい言葉について。
garbage(ガベージ) : 「ごみ」や「くず」、「がらくた」などのこと。
collection(コレクション) :「収集」や「回収」、「収集物」などのこと。
garbage + collection = GarbageCollection (ガベージコレクション)
つまりガベージコレクションは直訳でごみの収集 といった意味合いになります。
Javaでいうガベージコレクションとはプログラムで使用していないメモリを開放することです。
またガベージコレクタというものが、定期的にメモリの開放を行います。
このガベージコレクションはメモリリーク1の発生を防ぎ、
アプリケーションを効率よく動作させるための最適化に役立ちます。
この記事ではJavaのメモリ構造やガベージコレクションの役割、
ガベージコレクションチューニングの基礎知識について解説していこうとおもいます。
■ 目次
1. Javaのメモリ構造
Javaプログラムが動作するメモリ領域は主に「ヒープ領域」「スタック領域」「メタスペース」
に分かれていて、それぞれが以下のような異なる役割を持っています。
-
ヒープ領域
- Javaオブジェクトが生成される領域で、ガベージコレクションの対象となる。
- Young領域とOld領域に分かれ、短命なオブジェクトはYoung領域、長命なオブジェクトはOld領域に配置される。
更にはYoung領域内で Eden と Survivor スペースに分かれていて、新しいオブジェクトがまずEdenに配置され、
サイクルごとに生き残ったものがSurvivorスペースに移動されます。
-
スタック領域
- メソッドの呼び出しやローカル変数が管理される領域。
- メモリの割り当てや解放が自動で行われる。
-
メタスペース
- Java 8以降で導入された領域で、クラスメタデータが保存される場所。
- ヒープの外側に配置されており、必要に応じて拡張される。
このメタスペースはJava 8以前は「Permanent Generation」として扱われていた領域で、
Java 8からメタスペースが導入されたことでヒープ外にクラスメタデータが格納され、メモリリークの問題が改善されています。
2. ガベージコレクションの基本
Javaのガベージコレクションは不要になったオブジェクト(ガベージ)を自動的に回収する仕組みのことです。
この仕組みによりメモリの解放が自動化されプログラマが手動で管理する必要がなくなるため、メモリリークが起きにくい設計になっています。
ガベージコレクションはヒープメモリが一杯になってしまったり、特定のメモリ使用状況やアプリケーションのアイドル状態、設定された条件下などで自動的にトリガーされる際に発生します。
3. 代表的なガベージコレクションアルゴリズム
Javaには以下のような代表的なガベージコレクションのアルゴリズムが存在しており、用途に応じて選択されます。
種類 | 説明 |
---|---|
Serial GC | 単一スレッドで動作し、スループットには不向き 開発用環境や少量メモリの環境で使用 |
Parallel GC | 複数スレッドで並列に動作し、効率的にメモリを解放 高スループットが求められるアプリケーションに適している |
G1 GC | 複雑なメモリレイアウトに対応して遅延を最小限に抑える 大量のメモリを使用する大規模なアプリケーションに適している |
...など
ガベージコレクション アルゴリズムの指定方法
例えばG1 GCを使用する場合には、JVMオプション2で以下のように指定します。
-XX:+UseG1GC
4. ガベージコレクションチューニングの基礎
ガベージコレクションのチューニングはアプリケーションのパフォーマンスを向上させるために行います。
ガベージコレクションが発生する頻度やその際の遅延を調整することで、
パフォーマンスに影響を与えるガベージコレクションの影響を最小限に抑える目的があります。
チューニングの基本手法
-
ヒープサイズの設定
- ヒープサイズの上限を適切に設定しガベージコレクションが頻発するのを防ぐため、
- 以下のように 最大サイズ(Xmx) と 初期サイズ(Xms)を設定します。
(具体的な値はマシンや環境のメモリよって適宜変更します。)
-Xmx2g -Xms2g
ガベージコレクションログの有効化
以下の設定でガベージコレクションの動作状況をログとして出力してパフォーマンスの確認に役立てます。
-Xlog:gc*:file=gc.log:tags,time,uptime
-
アプリケーションのメモリ使用状況のモニタリング
- Java Mission Controlなどのツールでメモリの使用状況を可視化、
- 適切なガベージコレクションのタイミングやメモリ割り当ての改善を行います。
最新のJVMではZGC3やShenandoah4といった低遅延ガベージコレクションも利用可能で、
上記は特にリアルタイムアプリケーションやレスポンスが重要なシステムで有効です。
ZGCはヒープサイズに影響を受けにくく、数TBのメモリでも遅延が1ミリ秒以内になるように設計されているようです。
5. まとめ
- Javaのメモリ構造を理解することで、メモリ効率や最適化が可能
- ヒープ領域、スタック領域、メタスペースの役割を把握
- ガベージコレクションは不要なオブジェクトの自動回収を行い、メモリリークを防ぐ
- Serial、Parallel、G1など、環境に応じてGCアルゴリズムを選択
- ガベージコレクションチューニングで、アプリケーションパフォーマンスの向上が可能
- ヒープサイズの設定や**ログの活用が有効な手法