Java对象存储分三处:堆存对象实例,栈存引用和局部变量,方法区存类结构和静态变量;三者协同实现对象创建、访问与生命周期管理。

Java 对象的存储不是放在一个地方,而是按数据性质和生命周期拆开存放——对象本身在堆里,引用在栈里,而它的“设计图纸”(类结构、静态变量等)在方法区。
堆:所有对象实例的统一仓库
堆是 JVM 中最大、线程共享的内存区域,所有 new 出来的对象和数组都存在这里。比如 new Person("Alice", 20) 创建的 Person 实例,整个对象(包括 name、age 字段值)都分配在堆中。堆还被划分为新生代(Eden + Survivor)和老年代,由垃圾回收器(GC)自动管理生命周期。对象只要还有至少一个有效引用指向它,就不会被回收;一旦不可达,就进入 GC 待回收队列。
栈:每个线程独享的“工作台”
每个线程启动时都会分配一个私有栈,方法每调用一次,就压入一个栈帧。栈帧里存的是:
• 局部变量(如 int x = 5、String s)
• 方法参数
• 操作数栈和方法出口信息
其中,基本类型(int、boolean 等)的值直接存栈上;而引用类型(如 Person p)只存一个 4 字节(32 位)或 8 字节(64 位)的地址,这个地址指向堆中的真实对象。方法执行结束,栈帧立刻弹出,局部变量和引用随之消失。
方法区:存放类的“元信息”
方法区(JDK 8 后常称“元空间”,但逻辑作用一致)是线程共享区域,保存的是类加载后产生的静态结构,包括:
• 类的全限定名、字段/方法的字节码、访问修饰符
• 静态变量(static int count)
• 运行时常量池(字符串字面量、final 基本类型常量等)
• 已编译的 JIT 代码缓存
注意:静态变量本身存在方法区,但它若引用了对象(如 static List<string> list = new ArrayList()</string>),那么 list 这个引用存方法区,而 ArrayList 实例仍落在堆中。
三者协作的一个典型例子
执行以下代码时:
public static void main(String[] args) {<br>
Person p = new Person("Tom", 30);<br>
System.out.println(p.getName());<br>
}•
"Tom" 和 30 作为对象字段,连同 Person 实例一起存于堆• 变量
p 是一个引用,存于 main 方法的栈帧中,指向堆中那个 Person•
Person.class 的结构、getName() 方法字节码、static 成员等,都加载并驻留在方法区


















