🧠 【初心者向け】Stack と Heap の違いをやさしく解説
Java プログラムが動く裏側では、
Stack(スタック) と Heap(ヒープ) という2つのメモリ領域が常に働いています。
「何となく聞いたことはあるけど、結局どう違うの?」
「StackOverflowError とか GC とか、いまいち仕組みが分からない…」
そんな声をよく聞くので、
この記事では 図解とシンプルな例 を使って、
Stack と Heap の違いを “はじめてでも分かる形” で整理します。
結論
・Stack は「メソッドの作業スペース」(高速・自動破棄)
・Heap は「new したオブジェクトの置き場」(柔軟・GCで管理される)
とりあえずこの図を見てほしい👇
┌──────────┐ ┌────────────┐
│ Stack │ │ Heap │
│ ・ローカル変数 │ │ ・newした実体 │
│ ・参照だけ置く │ │ ・List / Stringなど │
└──────────┘ └────────────┘
↑ 高速 ↑ 大きく柔軟
Stack=「机」
Heap=「倉庫」
と覚えるとイメージしやすいです。
Stack とは?(初心者向けの基本説明)
Stack は メソッド1つにつき1つの“作業スペース”が積み重なる領域 です。
🔹 メソッド呼び出しの流れ(図解)
main() 呼び出し
↓
┌──────────┐
│ Frame: main │
│ int x = 10 │ ← Stackに置かれる
└──────────┘
run() 呼び出し
↓
┌──────────┐
│ Frame: run │
│ User u │ ← 参照をStackに置く
└──────────┘
特徴:
- 小さく高速
- メソッド終了と同時に 一瞬で破棄
- 消し忘れ不可(自動管理)
Heap とは?(初心者向けの基本説明)
Heap は new で作ったオブジェクトの実体が置かれる倉庫 です。
┌────────────┐
│ Heap │
│ new User() │ ← 実体はここ
│ new ArrayList() │
│ new int[100] │
└────────────┘
Heap の特徴:
- 大容量
- 柔軟にオブジェクトを配置できる
- 不要になったら GC(ガーベジコレクション) が回収
- Stack より遅い(距離が遠いイメージ)
利用時の注意点・落とし穴
❌ 誤解1:プリミティブはStack、参照型はすべてHeap
→ 正しくは
参照は Stack、実体は Heap
❌ 誤解2:Stack のほうが速い=全部Stackに置けば速い
→ Stack はサイズ固定でオブジェクトを置けない
❌ 誤解3:Heap は参照が消えた瞬間に解放される
→ GC のタイミング次第。即時解放ではない
ここまでのまとめ(初心者向け)
[Stack]
・メソッド呼び出し
・参照
・ローカル変数
・高速&自動破棄
[Heap]
・newしたオブジェクト
・柔軟だが遅め
・GCが管理
最重要ポイントは
参照は Stack、実体は Heap
です。
▼▼ ここから深掘り・ニッチ編 ▼▼
【後半:ニッチ編】Stack と Heap の内部構造
Java の実行時、Stack と Heap は JVM によって厳密に管理されています。
その内部イメージを図解で見ていきましょう。
内部構造:Stack は「スタックフレーム」の積み重ね
メソッド呼び出しごとに “スタックフレーム” が積まれます。
┌─────────┐
│ Frame: calc │ ← 上に積まれる
│ ローカル変数 │
└─────────┘
┌─────────┐
│ Frame: main │
└─────────┘
深すぎる再帰で
StackOverflowError が起きるのはこの構造のせい。
内部構造:Heap は「世代別(Young / Old)」で管理される
Heap は以下のように分割されています👇
Heap
├ Young Generation(短命が多い)
│ ├ Eden
│ └ Survivor(S0 / S1)
└ Old Generation(長寿オブジェクト)
🔹 GC が効率よく回る理由
- オブジェクトの大半はすぐ死ぬ(Eden で回収)
- 生き残る個体だけ Old に昇格(Promotion)
→ メモリ回収が効率化される
パフォーマンス最適化のポイント
✔ ArrayList / StringBuilder の初期容量は重要
拡張=Heap再割り当てが発生するためコストが重い。
✔ 参照が残ると GC できない
静的フィールドやキャッシュに残り続けるパターンは典型的なメモリリーク。
✔ new のしすぎで若い世代GC(Minor GC)が多発すると遅い
オブジェクト生成は安いが、多すぎると積もる。
スレッド・安全性の観点
ThreadA → StackA
ThreadB → StackB
↓
Heap(共有)
- Stack はスレッドごとに分離(安全)
- Heap は共有(競合のおそれ)
→ synchronized や volatile が登場する理由はここにある
この記事のまとめ
- Stack=高速な「作業台」
- Heap=柔軟な「倉庫」
- 参照は Stack、実体は Heap
- Heap は GC によって賢く管理される
- スレッドとメモリ領域の関係も重要
Deep Friendly Tech の一言(後書き)
Stack と Heap を理解すると、
「このコードはなぜ速い/遅いのか」
「このバグはなぜ起きるのか」
といった コードの本質が読めるエンジニア になります。
この基礎理解は Java だけでなく、
Go・Python・C#・C++・Rust にも応用できます。

コメント