转载声明:商业转载请联系作者获得授权,非商业转载请注明出处.原文来自 © 呆萌钟【玩转jvm系列】02.对象探秘
注意:本文描述的内容是基于HotSpot虚拟机。
对象的创建
对象创建流程图
对象创建流程
- 虚拟机遇到一条new指令
- 检查该指令参数在常量池中能否定位到对应类的符号引用
- 检查该类是否被加载、解析和初始化,如果没有必须先执行加载过程
- 虚拟机为新生对象分配内存
- 虚拟机将分配到的内存空间都初始化为零值
- 虚拟机对对象进行必要的设置(设置对象头)
- 执行<init>方法,把对象按照程序员的意愿进行初始化
对象的内存布局
在HotSpot虚拟机中,对象在内存中存储的布局可以分为三个区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
- 对象头包含两部分
- 第一部分存储对象自身的运行时数据,如HashCode、GC分代年龄、线程持有的锁等。
- 第二部分是类型指针,即对象指向它的类元数据的指针。如果对象是数组,对象头必须又一块用于记录数组长度的数据。
- 实例数部分(对象Body部分)
- 存储代码中所定义的各种类型的字段内容。
- 无论子父类,都需要记录下路。
- 对齐填充
- 对齐填充不是必然存在的,也没有特别含义,仅仅起占位符的作用。
- 对象的大小必须是8字节的整数倍,不足就通过对齐填充补充。
对象的访问定位
目前主流的访问方式有使用句柄和直接指针两种。
使用句柄方式
使用句柄访问的最大好处就是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改。
直接指针访问方式
直接指针访问的方式的最大好处就是速度更快,它节省了一次指针定位的时间开销,由于对象的访问在Java中非常频繁,因此这类开销积少成多后也是一项非常可观的执行成本。
小结
虚拟机Sun HotSpot,它使用的是第二种方式进行对象访问的,但从整个软件开发的范围看,各种语言和框架使用句柄来访问的情况也十分常见。