對象實例及其所有字段(基本類型、引用類型)均存儲在堆內存中。
| 數據類型 | 變量本身存儲位置 | 指向的數據存儲位置 |
|---|---|---|
| 基本類型局部變量 | 棧幀 | 棧幀 (值直接存儲) |
| 引用類型局部變量 | 棧幀 | 堆 (對象實例) |
| 對象實例字段 (基本類型) | 堆 (對象實例內部) | 堆 (對象實例內部,值直接內聯) |
| 對象實例字段 (引用類型) | 堆 (對象實例內部) | 堆 (另一個對象實例) |
| 靜態字段 | 元空間 / 堆 (類對象) | 堆 (對象實例) 或 元空間 (基本類型值) |
「凡是 new 出來的,都在堆;方法裡定義的變量,在棧。」
對象是 new 出來的,所以對象整體(含基本類型字段)在堆。
public class HeapDemo {
int primitiveField = 42; // 基本類型字段
String referenceField = "hi"; // 引用類型字段
public static void main(String[] args) {
HeapDemo obj = new HeapDemo(); // obj 引用在棧,對象實例在堆
// obj.primitiveField (42) 存儲在堆中 obj 實例的內存佈局裡
// obj.referenceField 指向堆中另一個 String 對象
}
}
JIT 編譯器若發現對象未逃逸出方法,可能將其標量替換為局部變量,字段值直接存入棧幀/寄存器,但這是運行時優化行為,不改變語言規範語義。