深入解析Java对象创建逻辑、内存布局以及访问机制

本文详细探讨了Java对象的创建逻辑、内存布局(包括对象头、实例数据和对齐填充),以及对象的访问定位(句柄访问与直接指针的区别)。重点介绍了MarkWord和KlassPoint的作用,以及Hotspot虚拟机的默认访问策略。
摘要由CSDN通过智能技术生成

一、对象的创建逻辑

在这里插入图片描述

二、对象的内存布局

在这里插入图片描述

2.1 对象头

在这里插入图片描述

  1. Mark Word(标记字段):大小是8个字节。默认存储的是对象的hashCode锁状态标识以及GC分代年龄。根据对象的状态复用自己的存储空间,即在运行期间Mark Word里的数据会随着锁状态标志位的变化而变化。
  2. Klass Point(类型指针):大小是4个字节。对象指向它的类元数据的指针,虚拟机通过这个指针来确定对象是哪个类的实例
  3. 若为对象数组,会存放对象的长度。

对象头扩展:

  • 通过java ClassLayout.parseClass(对象.class),可获得对象头的具体信息;
  • 整个对象的大小为java 16个字节(在64为虚拟机上对象的大小必须为8的倍数)。对象头的大小为12字节,其中MarkWord大小为8字节,Klass Word为4个字节;为什么上图中Klass Word为64bit呢?原因:进行了```指针压缩````。
  • 8个字节后七个字节存储hashcode信息,其中hashcode原本是不显示出来的,只有当调用对象的hashcode方法时,才会显示出来(即hashcode是计算出来的);第一个字节用于存放锁状态标识、gc年龄和对象状态。从上图中,可以得出以下信息:
    疑问1: 分代年龄为什么为15?,答:因为4位存储的最大数据就是15;
    其中偏向占用一位,用来判断是否加锁。当偏向对应的那一位为0时,说明没有加锁,对应对象状态为无锁状态(0 00),当偏向对应的那一位为1是,说明加锁了,分为5个状态,无锁、偏向锁、轻量级锁、重量级锁以及GC标志。

2.2 实例数据

存储类的数据信息父类的信息(大小和存储的数据有关)。

2.3 对齐填充

不是必须存在的,因为虚拟机要求对象起始地址是8字节的整数倍,仅仅是为了对齐(空对象的大小为8字节,因为会对齐填充)。

三、对象的访问定位

使用对象的时候,Java程序会通过栈上的reference数据来操作堆上的数据。通过什么方式定位访问堆中的对象,是由具体的虚拟机决定的。

3.1 句柄访问

reference指向的是对象的句柄地址
在这里插入图片描述

3.2 直接指针访问

reference指向的是对象地址
在这里插入图片描述

3.3 两者区别

句柄方式:因reference中指向的是对象稳定句柄地址,对象被移动时,只会改变句柄池中实例数据指针,而reference不需要被修改;解耦
直接指针方式:速度更快,节省了一次指针定位的时间开销。Hotspot默认使用的是直接指针方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃花猿

客官,赏点打酒钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值