🧠【初心者向け】Javaの Garbage Collection をやさしく解説(図解あり)
Java が「メモリ管理を自動で行ってくれる」と言われる理由が
Garbage Collection(GC) です。
でも初心者には GC が難しく感じるポイントがたくさんあります。
- JVM がメモリをどう管理しているか分からない
- Young/Old/Eden/Survivor の違い?
- “Stop the World” って何?
- 参照が切れたタイミングはいつ?
- GCログの読み方が分からない
- Mark & Sweep ってどう動くの?
この記事では、
GC の本質 → 図解 → 実務の勘所 → 内部構造
という順で、Java の GC を“直感的”に理解できるよう噛み砕きます。
✨ 結論
✔ GC の仕事は「使われなくなったオブジェクトを自動で回収」すること
✔ JVM のメモリは Young/Old で世代分けされている
✔ Young GC(Minor GC)と Old GC(Major GC)は役割が違う
✔ GC は Mark → Sweep → Compact の流れで動く
✔ “Stop the World” は GC中すべてのスレッドが止まる状態
✔ 設計の仕方で GC の負荷は大きく変わる
Garbage Collection とは何か?(本質から)
GC の本質はたった一つ。
「参照されていないオブジェクトを自動で消す仕組み」
Java では new したオブジェクトは
参照が残っている限り生存し、
参照がなくなったら GC が回収対象になります。
JVM のメモリ構造(まずはここを押さえる)
JVM のヒープは大きく2つに分かれています👇
✔ Young Generation(若い領域)
- Eden
- Survivor(S0/S1)
✔ Old Generation(古い領域)
🔹 図解(短線版)
Heap
├ Young Generation
│ ├ Eden
│ └ Survivor S0/S1
└ Old Generation
Young Generation(Eden/S0/S1)の仕組み
新しいオブジェクトは 必ず Eden に作られます。
流れ(超重要)
- Eden にオブジェクト作成
- Eden が満杯になったら Minor GC
- 生き残りは Survivor(S0)へ移動
- 次の GC で S1 に移動(コピー)
- コピーを数回繰り返し Old 領域へ昇格
🔹 図解(短線版)
Eden → S0 → S1 → Old
Minor GC(Young GC)は“軽量で高速”
Young GC は基本的に “軽くて高速” です。
理由:
- Young 領域は小さい
- オブジェクトの大半はすぐ死ぬ
- コピー方式なので断片化しない
そのため 頻繁に起きても問題ない と考えられています。
Old Generation(古い領域)の仕組み
長生きしたオブジェクトは Old 領域に格納されます。
Old 領域はアプリの主要データが集まるため
GCが重くなりがち。
✔ Major GC(Old GC)は重い
Major GC は Stop the World が長くなりやすく
パフォーマンスに影響する可能性があります。
Stop the World(StW)とは何か?
GC の中でも最も重要な概念。
「GCの間、すべてのスレッドが停止する現象」
🔹 図解
アプリスレッド:■■■■■ 停止 ■■■■■
GCスレッド : ★GC実行中★
- 計算も
- APIレスポンスも
- バッチも
全部止まる。
これを最小化するのが GC の最重要課題。
GCアルゴリズム(内部構造の本質)
JavaのGCは基本的に3ステップ👇
① Mark(生きているオブジェクトをマーク)
ルート(GC Root)からたどって「生存」マーク。
② Sweep(死んだオブジェクトを回収)
マークされていないオブジェクトを削除。
③ Compact(断片化の解消)
メモリを詰めて連続領域にする。
🔹 図解(短線版)
[生存][死][生存][死][死] → [生存][生存][空き][空き]
GC Root とは何か?(ニッチだけど重要)
GCは「どこから辿るか」を起点として判断します。
その起点が GC Root。
代表例👇
- スタック上の変数
- クラスの静的フィールド
- 実行中のスレッド
- JNI 参照
これらから辿れるオブジェクトは“生存”と判断されます。
GCの種類(Java 8 〜 最新版まで対応)
Java は複数GCアルゴリズムを提供しています👇
| GC名 | 特徴 |
|---|---|
| Serial GC | 単一スレッド、シンプル |
| Parallel GC | 高スループット向け |
| CMS(旧) | 低停止時間GC |
| G1 GC(主流) | StW が短くバランス良い |
| ZGC(最新) | 超低停止時間(ms未満) |
| Shenandoah | RedHat製、低遅延 |
Spring Boot / サーバアプリは
G1 GC が現在の標準 です。
実務で役立つ GC の勘所
✔ 避けるべきこと
- 大量の一時オブジェクト生成
- 文字列連結の
+を大量使用(→ StringBuilder へ) - 大きすぎるコレクションを保持する
- 不必要なキャッシュ
- 非効率な Stream パイプライン
✔ 追うべきGC指標
- GC回数
- Stop the World の時間
- Old GC発生頻度
- Heap使用率
- GCログの “Pause” 部分
ここまでのまとめ(初心者向け)
- GC は「使われなくなったオブジェクトの自動回収」
- Young(Eden/S0/S1)→ Old の2階層構造
- Minor GC は軽く、Major GC は重い
- Stop the World は“GC中すべて停止”
- GCの本質は Mark → Sweep → Compact
- G1 GC が現代の主流
Deep Friendly Tech の一言(後書き)
GC の理解は
Java の本当の基礎力 であり、
アプリの性能問題を読み解くための最高の武器になります。
GC を理解すると👇
- メモリ効率の良いコードが書ける
- パフォーマンス問題の切り分けが正確になる
- JVM の動きを読めるエンジニアになれる
ぜひ今日から、
あなたのコードの “オブジェクト寿命” に意識を向けてみてください。

コメント