SJ blog
Java
Z

信頼度ランク

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 YoungMinor GC
512M->128MGC前→GC後のヒープ使用量
(2048M)ヒープ総サイズ
45.678msGCにかかった時間

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チューニングは「ログを見る→仮説を立てる→パラメータを変える→効果を確認する」のサイクルで進めます。計測なしの勘チューニングは禁物です。