堆内存是jvm中唯一专门存储对象实例和数组的运行时区域,所有new创建的对象和显式数组均分配于此;其结构含对象头(mark word、类型指针)和对象体(实例变量),数组额外包含长度字段;按分代设计分为eden、survivor和老年代,新对象优先入eden,经minor gc存活后晋升,大对象可直接进入老年代;引用存于栈或静态区,指向堆中实体。

堆内存是 JVM 中唯一专门用于存储对象实例和数组的运行时区域,所有通过 new 创建的对象、显式声明的数组(如 int[] arr = new int[5]),都直接分配在堆中。
对象实例在堆中的存储结构
每个对象在堆中由两大部分组成:对象头(Object Header)和对象体(Instance Data)。
-
对象头包含:
• Mark Word:记录哈希码、GC分代年龄、锁状态(无锁/轻量级锁/重量级锁/偏向锁)等,内容随对象生命周期动态变化;
• 类型指针:指向方法区中该对象所属类的 Class 元数据(即类的运行时常量池、字段、方法等信息),支撑instanceof和向上转型等机制。 - 对象体:存放类定义的所有实例变量(非静态字段),包括从父类继承下来的字段(按宽度排序填充,含对齐补白)。
数组在堆中的特殊表示方式
数组也是对象,但其类型名不来自源码,而是 JVM 自动生成的内部表示:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 一维
int[]类型名为[I,二维byte[][]为[[B,String[]是[Ljava/lang/String;; - 所有同类型、同维度的数组共享同一个数组类(例如所有
int[10]和int[100]都是[I的实例); - 数组对象头后紧跟一个 长度字段(4 字节),再之后才是连续的元素数据区(如 10 个 int 占 40 字节)。
堆的分代结构如何影响对象存放
堆不是一块均质内存,而是按对象生命周期划分为新生代与老年代,直接影响对象初始分配与后续迁移:
- 绝大多数新对象优先分配在 Eden 区;
- Minor GC 后存活对象进入 Survivor 区(S0/S1),每经历一次 GC 年龄 +1;
- 达到阈值(默认 15 次)或 Survivor 空间不足时,对象晋升至 老年代;
- 大对象(如长字符串、大数组)可能直接分配到老年代,避免在 Eden 和 Survivor 之间多次复制。
引用与对象的分离存储
变量本身(如 HelloWorld obj)并不存对象,而是在栈帧或静态区中保存一个 引用值——本质是堆中对象起始地址(或经过压缩的 OOP)。这个引用指向堆中真实对象,实现“栈管引用、堆管实体”的协作模式。
例如:HelloWorld helloWorld = new HelloWorld(); 中,helloWorld 变量存在虚拟机栈里,new HelloWorld() 实例完整结构存在于堆中。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










