HotSpot虚拟机对象探秘
1. 对象的创建
对象创建的步骤
我们知道在Java中,创建一个对象仅仅需要一个new关键字,而在虚拟机中的创建优势怎样的呢?
- 当虚拟机遇到一条字节码new指令时,首先检查这条指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经加载,如果没有,必须先执行类加载过程。
- 分配内存
- 指针碰撞 相关收集器:Serial、ParNew
- 空闲列表 相关收集器:CMS
- 设置对象头信息
- 对象初始化
2. 对象的内存布局
- 对象头
- 运行时数据、哈希码(25 bit)、GC分代年龄(4 bit)、锁状态标志(2 bit)、线程持有的锁、偏向县城ID、偏向时间戳等。 (其中1 bit 固定为0)
- 类型指针(虚拟机通过这个指针确定该对象是哪个类的实例)
- 实例数据
存放对象的有效信息,即我们代码里定义的各种字段。 - 对齐填充
由于HotSpot虚拟机的自动内存管理系统要求任何对象的大小都必须8字节的整数倍,对象头部分已经是了,所以如果实例数据部分没有对齐的话,就需要对齐填充来补全。
3. 对象的访问定位
- 句柄访问
reference 中存储的是对象的句柄地址,句柄地址中包含了对象实例数据与类型数据的地址信息
- 优点:对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要被修改。
- 直接访问(HotSpot的使用方式)
reference 中存储的直接就是对象地址
- 优点:减少一次指针定位的时间开销,速度更快。