类仅存于方法区,不占堆栈;对象在堆中分配内存,引用变量存于栈中并存储对象地址。

类本身不占堆或栈,它只是模板;对象才是实际内存分配的主体——创建时落在堆里,而指向它的变量(引用)存于栈中。这是 Java 内存协作最基础也最关键的交互方式。
类:只在方法区加载,不参与堆栈分配
类(.class 文件)被加载进 JVM 后,存放在**方法区**(JDK 8+ 是元空间),包括字段定义、方法字节码、静态变量等。它不占用堆或栈,也不随 new 调用而复制。你写 class Person { String name; },这只是蓝图,没生成任何运行时数据。
对象:new 出来就进堆,内容全在堆中
每次执行 new Person(),JVM 就在堆中划分一块连续内存,存放:
- 所有实例字段(如 name 字符串的引用,或 int age 的值)
- 对象头(哈希码、GC 分代年龄、锁状态等)
- 对齐填充(保证 8 字节对齐)
这个对象从诞生起就独立存在于堆中,生命周期由 GC 管理,与哪个方法调用它无关。
引用变量:栈上只存“地址”,不是对象本身
当你写 Person p = new Person();:
- p 这个变量是局部变量,存在当前方法的**栈帧局部变量表**里
- 它存储的不是 Person 对象,而是一个 4 或 8 字节的**内存地址值**(JVM 内部表示),指向堆中那个真实对象
- 多个引用(比如 Person q = p;)可以同时指向堆中同一个对象——改 q.name,p.name 也会变,因为它们看的是同一块堆内存
方法调用时的完整协作流程
以 void printName(Person p) { System.out.println(p.name); } 为例:
- 调用时,参数 p(引用值)被复制进新栈帧的局部变量表 → 栈操作
- 方法体内访问 p.name:先从栈取地址,再按地址跳转到堆中读取 name 字段 → 堆栈联动
- 方法结束,栈帧弹出,p 这个引用变量消失 → 但堆中对象是否回收,取决于还有没有其他引用指向它
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











