Java面试必考问题:对象在内存中是如何布局的?

createh53个月前 (02-01)技术教程33

对象的内存布局
在HotSpot虚拟机中,对象在内存中的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对象填充(Padding)。

实例数据: 包括了对象的所有成员变量,大小由各变量的类型决定,包括基本类型和引用类型,这是对象真正存储的有效信息;

对齐填充: 由于虚拟机要求对象起始地址必须是8字节的整数倍,填充数据的存在主要是为了字节对齐。

对象头: HotSpot虚拟机的对象头主要包括两部分数据:标记字段(Mark Word)、类型指针(Class Pointer)。如果是数组的话,还包括数组长度,不是数组就没这部分。

虚拟机通过对象头的这个类型指针(也称为Klass Word)来确定这个对象是哪个类的实例。下面我们重点介绍一下对象头的Mark word。

Mark word

Mark Word 用于存储对象自身的运行时数据,Java对象头以一字宽的长度存储Mark Word,里面包含了对象的hashCode,分代年龄和锁标记位。

在32位虚拟机中,1字宽等于4字节,即32bit;在64位虚拟机下,1字宽等于64bit。

运行期间,Mark Word的数据类型会随着锁标志位的改变而改变,一共有以下几种状态:无锁态、偏向锁、轻量级锁、重量级锁和可回收(GC标志)。

回顾前文介绍过 synchronized 关键字为临界区代码加的是对象锁,也就是重量级锁,是通过监视器对象(ObjectMonitor)来实现线程互斥的,有时也被翻译为管程,其底层是依赖于操作系统的互斥量。当对象的锁状态为重量级锁时,Mark Word中的指针就指向了Monitor的地址。

由于互斥锁的线程切换系统开销太大,所以后来Java虚拟机又引入了开销更小的偏向锁和轻量级锁,适用于线程竞争不激烈的场合使用。JVM可以通过参数 -XX:-UseBiasedLocking 选择开启或不开启偏向锁。

如果不开启偏向锁,那么刚创建的对象的锁状态就是无锁态,即锁标志位是01,Mark word中存储的是对象hashcode;如果开启偏向锁,那么刚创建的对象的锁状态是偏向锁状态,线程Id为0,表示尚未有线程获取,不偏向任何线程;偏向锁被线程获取以后,Mark word就存储线程Id。

开启偏向锁的JVM,随着线程竞争的升级,会将偏向锁升级为轻量级锁,再进一步膨胀为重量级锁。对象的Mark word中的数据和锁标志位也会随之改变。

当一个对象被标记了GC标志,那么这个对象即将被垃圾回收,Mark Word中的数据自然是空的了。

我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法,欢迎大家关注,谢谢。

相关文章

32位已死,对安卓和苹果意味着什么?

Arm宣布,从2023年起,其所有新智能手机CPU内核都将仅为64位,且没有32位兼容模式。2013年,苹果就在iPhone 5s中使用了64位A7处理器,我们开始拥有支持64位的智能手机处理器。不久...

什么?Java 中的锁还有状态?(java中锁的概念)

线程如果锁住了某个资源,致使其他线程无法访问的这种锁被称为悲观锁,相反,线程不锁住资源的锁被称为乐观锁,而自旋锁是基于 CAS 机制实现的,CAS又是乐观锁的一种实现,那么对于锁来说,多个线程同步访问...

最全JVM内存调优详解(调整jvm内存)

一、前提JVM性能调优牵扯到各方面的取舍与平衡,往往是牵一发而动全身,需要全盘考虑各方面的影响。在优化时候,切勿凭感觉或经验主义进行调整,而是需要通过系统运行的客观数据指标,不断找到最优解。同时,在进...

纯干货!Eclipse的安装与使用(eclipse安装教程csdn)

之前有人给小华君留言,说让小华君讲一讲Eclipse,那好,我们今天就简单地讲一下。讲得也是基础部分,如题,主要是Eclipse的安装与使用。废话不多说,开始讲。Eclipse是Java开发的集成开发...

我的世界内存错误解决方法详解(我的世界内存耗尽)

这次搞趣网小编为诸位我的世界玩家带来的是我的世界内存错误解决方法详解,希望诸位我的世界玩家会喜欢。我的世界内存错误解决方法详解有的玩家估计是自己装的是32位的JAVA,尝试将最大内存调节到小于1G。这...