HotSpot虚拟机对象探秘

1. 对象的创建

对象创建的步骤
我们知道在Java中,创建一个对象仅仅需要一个new关键字,而在虚拟机中的创建优势怎样的呢?

  1. 当虚拟机遇到一条字节码new指令时,首先检查这条指令的参数能否在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经加载,如果没有,必须先执行类加载过程。
  2. 分配内存
    • 指针碰撞 相关收集器:Serial、ParNew
    • 空闲列表 相关收集器:CMS
  3. 设置对象头信息
  4. 对象初始化

2. 对象的内存布局

  1. 对象头
    1. 运行时数据、哈希码(25 bit)、GC分代年龄(4 bit)、锁状态标志(2 bit)、线程持有的锁、偏向县城ID、偏向时间戳等。 (其中1 bit 固定为0)
    2. 类型指针(虚拟机通过这个指针确定该对象是哪个类的实例)
  2. 实例数据
    存放对象的有效信息,即我们代码里定义的各种字段。
  3. 对齐填充
    由于HotSpot虚拟机的自动内存管理系统要求任何对象的大小都必须8字节的整数倍,对象头部分已经是了,所以如果实例数据部分没有对齐的话,就需要对齐填充来补全。

3. 对象的访问定位

  1. 句柄访问
    reference 中存储的是对象的句柄地址,句柄地址中包含了对象实例数据与类型数据的地址信息
  • 优点:对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要被修改。
  1. 直接访问(HotSpot的使用方式)
    reference 中存储的直接就是对象地址
  • 优点:减少一次指针定位的时间开销,速度更快。