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

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

对象的内存布局
在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位系统装8g内存条能用吗?为什么?

关于32位和64位,这个概念一直让人比较懵。在买电脑的时候,我们看到过32位和64位CPU。下软件的时候,我们也看到过32位或64位的软件。就连装虚拟机的时候,我们也看过32位和64位的系统。在写代码...

java采用int32作为hashcode,会不会出现更高的碰撞概率?

在Java中,hashCode方法通常返回一个int类型的值,其范围是从-2^31到2^31-1的整数。尽管这个范围实际上可以容纳2^31个不同的哈希值,但在日常讨论和某些上下文中,可能会将其简化为"...

我的世界内存错误提示怎么办如何修改

我的世界是一款沙盒游戏,所呈现的世界并不是华丽的画面与特效,而是注重在游戏性上面。在游戏中,常常有玩家反映,经常提示内存错误,怎么办?有的玩家估计是自己装的是32位的Java,尝试将最大内存调节到小于...

程序员,背熟这99道Java多线程面试题,和面试官扯皮就没问题了

作者:享学课堂链接:https://www.jianshu.com/p/3e88a5fe75f0前言今天给大家更新的是一篇关于多线程面试的文章,也是霸哥根据时下热门的面试内容给大家进行总结的,如有雷同...

二 JAVA语言基础之 基本数据类型(java的基本数据类型有哪些并简单叙述)

前面我们搭建了JAVA的开发环境和开发工具,今天我们正式进入JAVA基础语法的学习。首先认知下JAVA的八大基本类型:Java中主要有八种基本数据类型:1、整型:byte、short、int、long...