Java 擁有自動垃圾回收(GC),但若不理解底層內存模型,極易寫出內存洩漏、OOM 或性能低下的代碼。本文系統梳理棧、堆、數據共享、靜態/動態內存分配機制,助你實現「事半功倍」的優化。
一、核心概念
1. 棧 —— 線程私有,先進後出
- 存放:基本類型變量(int、char 等)、對象引用變量。
- 特點:每條線程獨享一個棧,生命週期與線程綁定,速度極快。
- 比喻:單口桶,放入 P,I,N,S,I,L,Y,取出順序為 Y,L,I,S,N,I,P。

2. 堆 —— 線程共享,GC 主戰場
- 存放:
new 出來的對象、數組實體。
- 特點:所有線程共享同一堆,GC 掃描回收無引用對象。
- 關係:棧中引用指向堆中實體,程序執行本質是棧堆交互。
3. 數據共享 —— 僅發生在堆
int a = 3; int b = 3;
// 棧創建 a、b 引用;堆僅創建一個 3,a、b 指向同一地址
- 基本類型常量池(Integer -128~127、String 常量等)實現共享,節省內存。
- 棧數據線程私有,無法共享。
4. 靜態內存 —— 編譯期確定大小
類變量(static)、基本類型局部變量、方法參數等,類加載或方法進棧時直接分配固定大小空間。
5. 動態內存 —— 運行期按需分配
對象實例、數組、集合擴容等,大小不可預知,運行時向堆申請。
二、內存分配機制圖解
可類比 C 指針:棧存指針(引用),指向堆中實際數據地址。


- 靜態變量:類加載階段分配(方法區/元空間)。
- 動態變量:首次
new 或方法調用時分配。
三、實戰啟示
- 避免大對象進棧:只存引用,實體扔堆。
- 善用常量池:
String s = "abc" 優於 new String("abc")。
- 關注對象生命週期:及時斷開引用(置 null),助 GC 回收。
- 監控堆/棧大小:
-Xms、-Xmx、-Xss 調優參數。
- 理解逃逸分析:JIT 可將未逃逸對象標量替換、棧上分配、同步消除。
掌握內存模型,不再盲目依賴 GC,才能寫出高性能、穩定的 Java 應用。