java堆中句柄池_JVM高级特性-二、JVM在堆中对象的分配、布局、访问过程

前面介绍了jvm运行时数据区域后,下面讲解下对内存中数据的其他细节,看他们是如何创建、布局及访问的

一、对象的创建

1.对象的分配

对象的创建分配方式主要有两种:指针碰撞和空闲列表

指针碰撞:

假设堆内存中是绝对规整的,那么,在为新对象分配内存空间时,只需要将指针向空闲空间方向移动新对象

所需大小的一段出来即可。

一般使用带有compact(整理)过程的收集器时,使用指针碰撞

空闲列表:

如果内存不是规整的,这时就需要维护一个列表,记录哪些内存是空闲的,在分配空间时,从列表中找出一块

足够大的空间划分为对象实例并更新列表记录

使用基于mark-sweep算法的收集器时,使用空闲列表

2.对象的初始化及设置

初始化:内存分配完成后就是对对象进行初始化,虚拟机将初始化的内存空间都初始化为0值,

这就是为什么对象的实例字段在java代码中不需要初始化也可以使用

设置:之后,虚拟机对对象进行一些必要设置,主要是往对象头中存入类的元数据信息、对象的哈希值、分代年龄等。

init: 经过上面两步后对象创建完成,但所有字段还都是0值。最后就是执行init方法,按程序员的意思初始化对象

完成上述三步后,一个对象就算创建完成。

二、对象的内存布局

对象在内存中存储的布局主要分为三部分,对象头、实例数据、对齐填充

对象头:

对象头在对象设置阶段提到过,即在设置阶段会向对象头中存入一些类的元数据信息、哈希值、分代年龄等

对象中主要分为两部分:运行时数据和类型指针

运行时数据:主要存储上面对象设置阶段存储的哈希码、分代信息、锁状态标识、线程持有的锁等。

类型指针:主要存储对象的类元数据的指针,即这个对象是哪个类的实例,此外,如果对象类型是数组,

对象头中还会存储一个代表数据长度的数据

对齐填充:不是必然存在的,在Hotspot中,要求对象起始地址必须是8字节的倍数,

当对象实例部分没对齐时,用对齐填充来补全。

三、对象的访问定位

java程序是通过栈上的reference数据来操作对象实例的,因此它只是一个引用,具体定位方式jvm有不同实现

主流实现方式有两种:使用句柄和直接指针

句柄池:

原理:java堆中会划出一片区域作为句柄池,reference存储的就是句柄地址,

里面包含对象实例数据的指针和对象类型指针

好处:如果对象被移动,只需改变句柄池中存储的地址

直接指针

原理:如果使用的是直接指针,那么reference中存储的就是对象的地址

好处:省去了一次定位的时间,效率更高

Hotspot使用的是直接指针方式

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值