成员变量随对象实例存储在堆内存中,包括基本类型值和引用类型地址;静态变量存于方法区,被所有实例共享;数组对象及其元素也统一分配在堆中。

成员变量属于对象实例的一部分,它们和对象实例一起存储在堆内存中。
对象实例在堆中占据连续内存块
当使用 new 创建一个对象时(如 new Person()),JVM 在堆中分配一块连续的内存空间。这块空间不仅存放对象头(包含哈希码、GC分代年龄、锁状态等元数据),还紧跟着存放该对象所有非静态成员变量(包括基本类型和引用类型)的值。
- 基本类型(如 int、boolean)的值直接存放在该内存块内;
- 引用类型(如 String、自定义类对象)的值是地址,也存放在该块中,但其所指向的实际对象仍位于堆中其他位置(可能为 null)。
成员变量按声明顺序和类型大小布局(受JVM优化影响)
JVM 通常会对字段进行重排序以提升内存对齐效率(如把 long 和 double 放在一起),但逻辑上仍按类定义顺序初始化。例如:
class Example {
byte a; // 占1字节
int b; // 占4字节
byte c; // 占1字节
long d; // 占8字节
}
实际内存布局可能为:a-c-(填充3字节)-b-d,以保证 b 地址对齐、d 能被8整除,提升CPU读取效率。
静态变量不参与对象实例的堆内存布局
static 成员变量不属于任何对象实例,它被存储在方法区(JDK 8+ 为元空间),与堆中的对象实例完全分离。每个类只有一个静态变量副本,所有实例共享它。
- 修改某个实例通过 static 引用改变的值,会影响所有实例;
- 但修改非静态成员变量,只影响当前对象所占的那块堆内存。
数组对象和其元素也在堆中统一管理
数组本身是一个对象,创建后同样分配在堆中。数组对象内存结构包括:对象头 + 数组长度 + 元素序列。例如 new int[3] 在堆中开辟一块含3个 int 值的空间;new String[2] 则开辟2个引用位置(初始为 null),每个引用可再指向堆中其他 String 对象。
















