HotSpot JVM 对象探秘 《深入理解Java虚拟机》

上面大致了解虚拟机的内存的概况后,接下来将继续了解这些内存中的数据的更多的细节。接下来本章会限定具体的虚拟机和其中某一块内存区域上讨论 如何创建,如何布局,以及如何访问 这三个细节问题。


1、如何创建 - 对象的创建

 

上图简要说明:

步骤三:为新生对象分配内存,等同于把一块确定大小的内存从Java堆中划分出来,如何划分,取决于Java堆是否规整。

“指针碰撞”方式: java堆中内存是绝对规整的, 所有已经使用过的在一边,空间的在另一边,中间放着一个指针作为分界点的指示器。当需要为新对象分配内存的时候,指针往空闲的一边移动需要分配的内存大小。

“空闲列表”方式:JVM 维护了一个列表,记录了哪些内存块是可用的。在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。


2、如何布局 - 对象的内存布局

对象的内存中存储的布局可以分为3块区域: 对象头,实例数据,对其填充。

 对象头:其中包括两部分的信息。第一部分用于存储对象自身的运行时数据,如 哈希码,GC分代年龄,锁状态标志,线程持有锁,偏向线程ID,偏向时间戳等。这部分数据的长度在32,64位JVM中分别为32bit,64bit官方称它为“Mark Word”。关于锁状态,标志位解释,另行开篇说明。

对象头信息是与对象自身定义的数据无关的额外的存储成本,考录到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,他会根据对象的状态复用自己的存储空间。

对象头的另外一部分是类型指针,即对象指向他的类元数据的指针。JVM通过这个指针确定对象是哪个类的实例。

实例数据:这部分数据是对象真正存储的有效信息。也是在程序代码中所定义的各种类型的字段内容。

对齐填充:这部分数据并不是必然存才的, 也没有特别的含义。他仅仅是占位符的作用,由于HotSpot VM 的自动内存管理系统要求对象起始地址必须是8字节的整数倍。就是说对象的大小必须是8字节的整数倍。因此当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。 


3、对象的访问定位

建立对象是为了使用对象,我们的Java程序需要通过栈上的reference数据来操作堆上的具体对象。目前主流的访问方式有使用句柄和直接指针两种。

句柄方式:使用句柄的话,Java堆中将划分出一块内存来作为句柄池,reference中存储的是对象的句柄地址,而句柄中包含了对象的实例数据和类型数据各自的具体的地址信息,其好处就是reference中存放的是稳定的句柄地址,在对象被移动时只会改变句柄中的实际数据指针,而reference 本身不用改变。如下图:

直接指针方式:那么Java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,而reference中存储的直接就是对象地址。最大好处就是访问速度快。如下图

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值