信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
JavaのGarbage Collection理解と最適化 — GCの仕組みからチューニングまで
Java GCの仕組み(GC世代、G1GC/ZGC/SerialGC)、GCログの読み方、メモリチューニングの具体的な手順を解説します。
一言結論
GCチューニングの第一歩はGCログを有効化して実際のPause時間とメモリ消費を計測することで、推測でヒープサイズを増やすより先にGCログの分析でボトルネックを特定するべきだ。
GCとは
不要になったオブジェクト(誰も参照していないオブジェクト)を自動的にメモリから解放する仕組みです。Javaでは手動でメモリを解放する必要がありません。
ヒープの構造(世代別GC)
Heap
├── Young Generation(新しいオブジェクト)
│ ├── Eden(最初にオブジェクトが配置される)
│ ├── Survivor S0(Minor GC後の生き残り)
│ └── Survivor S1
└── Old Generation(長命なオブジェクト)
(PermGen → Java 8以降 Metaspace に変更)
Minor GC(Young GC)
Eden 領域が満杯になると発生。短命なオブジェクトのほとんどがここで回収されます。頻繁に発生しますが、短時間(ミリ秒単位)。
Major GC / Full GC
Old 領域が満杯になると発生。時間がかかる(100ms〜数秒)。Stop-the-World が発生し、アプリが一時停止します。
GCアルゴリズムの種類
Serial GC
シングルスレッドGC。小さいアプリ・組み込み向け。
java -XX:+UseSerialGC
G1GC(Java 9以降のデフォルト)
ヒープをリージョンに分割して並列GC。低レイテンシと高スループットのバランスが良い。
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200
ZGC(Java 15以降で本番利用可)
ほぼ全ての処理を並列で行い、停止時間を数ミリ秒以下に抑える。大容量ヒープ向け。
java -XX:+UseZGC
Shenandoah GC
ZGC と同様の低レイテンシGC(OpenJDK系)。
java -XX:+UseShenandoahGC
GCログを出力する
# Java 9以降
java -Xlog:gc*:file=gc.log:time,uptime,level:filecount=5,filesize=20m -jar app.jar
# Java 8
java -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log -jar app.jar
GCログの読み方
[2026-04-05T10:30:00.123+0900][3.456s][info][gc] GC(42) Pause Young (Normal) (G1 Evacuation Pause) 512M->128M(2048M) 45.678ms
| フィールド | 説明 |
|---|---|
GC(42) | GCの通し番号 |
Pause Young | Minor GC |
512M->128M | GC前→GC後のヒープ使用量 |
(2048M) | ヒープ総サイズ |
45.678ms | GCにかかった時間 |
GC チューニングのパラメータ
# ヒープサイズ
-Xms512m # 初期ヒープ
-Xmx4g # 最大ヒープ(-Xms と同じにすると動的調整が減る)
# G1GC 設定
-XX:MaxGCPauseMillis=200 # 目標停止時間(ms)
-XX:G1HeapRegionSize=16m # リージョンサイズ(1M〜32M)
-XX:G1NewSizePercent=20 # Young 領域の最小割合
-XX:G1MaxNewSizePercent=60 # Young 領域の最大割合
-XX:ConcGCThreads=4 # 並列GCスレッド数
# Metaspace
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
メモリリークの調査
# ヒープダンプを取得
jmap -dump:format=b,file=heap.hprof <PID>
# OOM 発生時に自動ダンプ
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -jar app.jar
# jstat でリアルタイム監視
jstat -gc <PID> 1000 # 1秒ごとにGC情報を表示
Eclipse MAT(Memory Analyzer Tool)でヒープダンプを解析:
- Leak Suspects Report で主要な原因を自動特定
- Dominator Tree で最大メモリ消費者を確認
よくあるGC問題と対処
Full GC が頻発する
原因: Old 領域が不足
対処: -Xmx を増やす、またはメモリリークを探す
GC 停止時間が長い(100ms超)
原因: GC のアルゴリズムが古い、ヒープが大きすぎる
対処: G1GC または ZGC に切り替える
Metaspace OOM
原因: クラスのロード数が多い
対処: -XX:MaxMetaspaceSize を増やす、不要なクラスローダーのリークを確認
jconsole / jvisualvm での監視
# JDKに含まれているGUI監視ツール
jconsole # シンプル
jvisualvm # 高機能(ヒープダンプ、プロファイラ付き)
まとめ
| アルゴリズム | 向いている場面 |
|---|---|
| Serial GC | 小さいアプリ・バッチ |
| G1GC | 汎用(デフォルト推奨) |
| ZGC | 低レイテンシが重要なサービス |
GCチューニングは「ログを見る→仮説を立てる→パラメータを変える→効果を確認する」のサイクルで進めます。計測なしの勘チューニングは禁物です。