+-------------------------+ | 方法區 | 類信息、常量、靜態變量、JIT編譯代碼 | (Metaspace/JDK8+) | +-------------------------+ | 堆 | new 出來的對象、數組(所有線程共享) | (GC 主戰場) | +-------------------------+ | 虛擬機棧 (線程私有) | 棧幀:局部變量表、操作數棧、動態鏈接、方法返回地址 | 本地方法棧 | Native 方法調用 | 程序計數器 | 當前線程執行字節碼行號 +-------------------------+
new 對象、數組在這裡分配| 創建方式 | 存儲位置 | 示例 |
|---|---|---|
| 字面量 | 常量池 | String s = "abc"; |
| new String() | 堆 | String s = new String("abc"); |
| 編譯期常量拼接 | 常量池(優化) | "a" + "b" + "c" → "abc" |
| 運行期變量拼接 | 堆 (StringBuilder) | s1 + s2 |
String s1 = "abc";
String s2 = "abc"; // s1 == s2 → true (常量池同一引用)
String s3 = new String("abc");
String s4 = new String("abc"); // s3 == s4 → false (堆不同對象)
s3.intern() == s1 // true (手動入池)
public void test() {
int date = 9; // 基本類型局部變量 → 棧
Test test = new Test(); // test引用→棧,對象→堆
test.change(date); // 參數傳值,i在新棧幀
BirthDate d1 = new BirthDate(7,7,1970); // d1引用→棧,對象→堆
} // 方法結束:棧幀彈出,date/test/d1引用消失;堆對象等待 GC
理解內存模型是排查 OOM、優化性能、寫出高質量並發代碼的前提。