JVM 虚拟机中的对象
本文将以 HotSpot 虚拟机为例,介绍虚拟机是如何管理对象的。
一、对象的创建
1. 类检查
当 JVM 遇到一条 new 指令时,首先检查能否在常量池中定位到类的符号引用,其次检查类是否已被加载、解析和初始化,如果没有,则先执行类的加载过程。
2. 分配内存
当类检查通过后,首先需要划分内存,即将一块确定大小的内存块从堆中划分出来
- 假如堆中的内存都是绝对规整的,已被使用的区域和未被使用的区域被界限严格分离开,那么只需要将界限移动便可以实现内存划分,这种划分方式被称为 “指针碰撞”
- 假如堆中的内存不是规整的,已被使用的区域和未被使用的区域交错在一起,则 JVM 需要维护一个用于指示空间使用情况的 “空闲列表”,划分时需要从列表中找到一个足够大的区域划分给对象,并更新 “空闲列表”
3. 初始化为零值
内存划分完成后,JVM 需要将划分到的内存空间都初始化为零值。这步操作保证了对象的属性能够在 Java 代码中不赋初值直接使用。
4. 对象头设置
对对象进行必要的设置,包括:对象所属的类、类元数据信息的寻找方式、对象哈希码等,这些信息会被存储在对象头中。
5. 对象初始化
执行对象的构造方法,完成对象的初始化。
二、对象的内存布局
对象的存储布局可以划分为三个部分:
对象头:
- 对象自身的运行时数据:哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等
- 类型指针:指向类型元数据
- 数据长度:如果对象是一个数组,则还有数组长度数据,以便 JVM 确定数组长度
实例数据
对齐填充:不一定存在,仅起占位作用
因为 HotSpot 虚拟机的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍,因此需要使用对齐填充将对象的大小填充为 8 的整数倍
三、对象的访问定位
Java 程序会通过栈上的对象引用来操作堆上的具体对象。
具体请看:
参考
- 深入理解 Java 虚拟机