实例变量在对象创建时随对象一起分配在堆内存中,类加载时不分配;每个对象独有一份,生命周期与对象一致,存储于堆中对象的实例数据部分。

实例变量(也叫成员变量)在对象创建时,是随着对象一起分配在堆内存中的,不是在类加载阶段就分配的。
分配时机:对象实例化那一刻
类加载时,静态变量(static字段)会在方法区(或JDK 8+的元空间+堆中Class对象)分配并初始化零值;但实例变量不会。只有当执行 new 指令、真正创建对象实例时,JVM才在堆中为该对象划分一块连续内存,其中就包含所有实例变量的空间。
- 这块内存大小由类结构在类加载完成后就已确定(含父类继承的实例字段)
- 分配位置通常优先在新生代的Eden区,大对象可能直接进入老年代
- 分配方式取决于垃圾收集器:规整堆用“指针碰撞”,碎片化堆用“空闲列表”
初始化顺序:先零值,再显式赋值
内存分配完成后,JVM立即对这块区域做两件事:
- 零值初始化:所有实例变量被设为默认值(int→0,boolean→false,引用→null),这一步不执行任何Java代码,由JVM底层保证线程安全
-
执行初始化逻辑:按源码顺序,把实例变量的显式初始值(如
int x = 5;)和实例代码块({ System.out.println("init"); })插入到构造方法中,在调用父类构造器之后、本类构造器主体之前执行
存储位置:堆中对象结构的一部分
一个Java对象在堆中的内存布局通常包括三部分:
- 对象头(Header):存储哈希码、GC分代年龄、锁状态、类型指针等
- 实例数据(Instance Data):就是所有实例变量的值,按字段宽度、继承关系和虚拟机优化(如字段重排序)排列
- 对齐填充(Padding):确保对象起始地址为8字节倍数,便于CPU访问
注意:栈中只存对象引用(即指向堆中该对象首地址的指针),真正的实例变量值永远在堆里。
与静态变量的关键区别
静态变量属于类,随类加载而存在,生命周期与类一致;实例变量属于对象,每个对象独有一份,随对象创建而诞生、随GC回收而消失。
- 静态变量存储在方法区(逻辑上)或与Class对象共存于堆(JDK 8+)
- 实例变量必须依附于具体对象,没有对象就没有它的内存空间
- 哪怕一个类有100个实例变量,没创建对象前,它们不占堆内存











