深入理解JVM——HotSpot对象创建

一、对象的创建过程

当虚拟机遇到一条含有new的指令时,会进行一系列对象创建的操作:

1.检查常量池中是否有即将要创建的这个对象所属的类的符号引用。

2.检查这个符号引用所代表的类是否已经被JVM加载。

3.根据方法区中该类的信息确定该类所需的内存大小

4.从堆中划分一块对应大小的内存空间给新的对象

5.为对象中的成员变量赋上初始值(默认初始化)

6.设置对象头中的信息

7.调用对象的构造函数进行初始化

七步骤:检查符号引用、检查JVM是否加载、确定对象所需大小、分配内存空间、默认初始化、设置对象头中的信息、执行构造函数。

 

二、对象的内存模型

对象在内存中分为三个部分:

1.对象头

2.实例数据

3.对齐补充

1.对象头

对象头中记录了对象在运行过程中所需要使用的一些数据:哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。

此外,对象头中可能还包含类型指针。通过指针能确定这个对象所属哪个类。

此外,如果对象是一个数组,那么对象头中还要包含数组长度。

 

2.实例数据

实例数据部分就是成员变量的值,其中包含父类的成员变量和本类的成员变量。

 

3.对齐补充

用于确保对象的总长度为8字节的整数倍。

HotSpot要求对象的总长度必须是8字节的整数倍。对象头一定是8字节的整数倍,但是实例数据部分的长度是任意的,因此需要补充字段确保整个对象的总长度为8的整数倍。

 

三、访问对象的过程

引用类型的变量中存放的是一个地址,那么根据地址类型的不同,对象有不同的访问方式:

目前的主流的访问方式有使用句柄访问直接指针访问两种。

 

1.句柄访问

Java堆中会划分出一块内存作为句柄池,栈中的reference指向对象的句柄地址,句柄中包含了对象实例数据和类型数据各自的具体地址信息,如下图所示。

 

2.直接指针访问

reference中存储的就是对象地址。

 

3.比较

总的来说,这两种对象访问定位方式各有千秋。使用句柄访问的最大好处就是reference中存储的是稳定的句柄地址,对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,reference本身不需要修改;而使用直接指针访问的最大好处就是速度快,节省了一次指针定位的时间开销。

HotSpot采用直接指针方式访问对象,因为它只需一次寻址操作,从而性能比句柄访问方式快一倍。但它需要额外的策略存储对象在方法区中类信息的地址。

 

参考:

来自 <https://blog.csdn.net/justloveyou_/article/details/71189093>

来自 <https://blog.csdn.net/u010425776/article/details/51190801>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值