问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

面试官发问:“对象头(object header)”里知多少?

发布网友 发布时间:2024-10-05 05:07

我来回答

1个回答

热心网友 时间:2024-11-19 07:01

在家办公的第N周。

不知道公司还在不在了....

言归正传,回到正文“对象头”

对于学习Java来说, 对象头可以是入门的知识点之一。

假设有一扇门通向深入Java语言,那么对象头就是“进门须知”的这么一个地位,没什么技术要点,但是需要知道。

“synchronized的锁标志存哪了?”,“对象多大岁数呀对象的分代年龄在哪看”等等,刚学Java时免不了这些疑问,这些就和对象头息息相关。

如果对“对象头”不清晰的读者,可以继续往下看了,本文将展示于你“对象”的里大致都装了什么.

先抛出基本概念,后面笔者有具体的实践。

对象头(Object header)是直译过来的,未免有些生硬,依笔者看叫“对象名片”还能上口一些,主要包含了对象的基本信息,比如:

identity hash code是指不经重写过由jvm计算的hashcode.

整个对象头由两个部分组成,即:klass pointer和Mark Word.

当然了,介绍这两个东西之前,此处需要强调一下:本文默认是基于jdk1.8并且64位环境进行描述的,算是一个标配。

klass pointer一般占32个bit即4个字节,如果你有足够的原因关闭默认的指针压缩,即启动参数加上了-XX:-UseCompressedOops那么它就占64个bit。

不过此处还有一个细节:根据计算,堆大小超过32GB后,就算不关指针压缩并不会报错,只是指针压缩会失效。

但是这个笔者到是没有进行实际测试,原因嘛.... 堆大小要32GB+内存, 还要留给非堆和OS一些内存,这种内存的机器是笔者三线小厂得不到的...

klass pointer的存储内容是一个指针,指向了其类元数据的信息,jvm使用该指针来确定此对象是类的哪个实例。

Mark Word在64位虚拟机下,也就是占用64位大小即8个字节的空间。

内具体容包括:

如果你看cms_free这个字体有点奇怪那就对了,开始误画成了unused,后来反应过来默认开启“指针压缩”的情况,那么那一个bit应该是cms_free.

cms_free从名字就能看出和cms收集器有关系,因为cms算法是标记-清理的一款收集器,所以内存碎片问题是将不可达对象维护在一个列表free list中,笔者推测此处应该是标记对象是否在free list中.

关于cms_free的结论是笔者推测的,你大可不必相信,如果认为笔者说的不正确可以告诉我.

如果你觉得笔者说的不对,但是你又拿不出证据,倒也不用十分较真儿,毕竟jdk14 cms已经被移除了.

初学者对这些东西感到头大,可以先从无锁状态的那一行下的内容开始了解.

如果看完这些东西,回味一下笔者上面说的“mark word对于java程序员是比较重要的一块知识点”,相信你也知道原因了. 这部分和程序关系很大,比如:

为什么晋升到老年代的年龄设置(XX:MaxTenuringThreshold)不能超过15 ?

因为就给了age四个bit空间,最大就是1111(二进制)也就是15,多了没地方存.

为什么你的synchronized锁住的对象,没有“传说中的”偏向锁优化?

因为hashcode并不是对象实例化完就计算好的,是调用计算出来放在mark word里的。

你调用过hashcode方法(或者隐式调用:存到hashset里,map的key,调用了默认未经重写的toString()方法等等),把“坑位”占了,偏向锁想存的线程id没地方存了,自然就直接是轻量级锁了.

看起来设计的有点不合理但又透着合理,底层的设计就是这么朴实无华,且枯燥。

本文重点是介绍“对象头”,所以不会重点介绍锁,就如刚才说的“调用过hashcode再同步发现是轻量锁”,其实还有很多种情况, 比如: 在synchronized块内调用的hashcode计算方法,就算有了偏向锁也会被撤销,膨胀为重量级锁。如果有缘,你可能在未来能看到笔者单独描述锁的文章。

实践出真知,工欲善其事必先利其器,工具使用jol工具即可,openjdk提供的分析对象大小,布局等信息的工具。

本文使用最简单的maven引入工程的方式进行测试. 你也可以选择命令行的方式,两种使用方式都在上方jol的链接中有介绍。

引入jol之后,我们开始打印对象布局试试。

数组对象布局

如果你是第一次看jol打印的布局图,可以直接看笔者标注好的下图:

对象头的三个部分,分别印证了上文提到的klass pointer和Mark Word,以及数组独有的长度属性。

右侧分别用了三种进制展示了“每一行”的value, 呼应上文:

没有调用过原始的hashcode方法(包括System.identityHashCode方法), 那么hashcode位置都是0.

由图可得出结论,对象在刚实例化好的时候,非常“干净”,乍眼看去两排0,但是只有一个1显得十分突兀。

其实它是001,为上文提到的偏向锁标志+锁标志,所有锁的状态如下:

这回就清晰了,虽然有一个1,但其实是无锁的状态。

回到布局图,因为是数组对象,所以在第四行保存了数组长度,非数组对象自然是没有的。

对象大小的计算,也是非常精准的, 即:13224(一个int为四个字节乘3306) + 16 = 13240个字节。

自己实践的提示

看到对象布局设计的如此朴实无华,你也可以动手实践一下。

笔者也附上几个小提醒:

不注意这几点,你可能打印完一脸茫然,不知道哪些bit对应哪些字段,甚至和自己的预想结果不一样。

最后

对于对象的结构这一部分其实有很多细节值得你去拓展阅读, 本文只是简单的介绍了“Object header”这一小部分。

看完本文,有没有和笔者一样,想说一句:

底层的设计就是这么朴实无华,且枯燥。

开个玩笑, 事实上多看看, 你会发现非常有乐趣。

作者:Vt 链接: juejin.im/post/5e830f54... 来源:掘金
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
5数字寓意是什么意思 如何在 iPhone14上恢复已删除的照片? 红井源 醇香胡麻油 2.5L-购买最佳价格 python如何实现修改当前文件夹下所有文件名称? python遍历输出所有文件 用Python遍历指定文件夹下所有文件 Python:读取指定路径下的文件,含子文件夹,可指定文件类型 谁有治疗网瘾的好方法? 孩子有网瘾又叛逆怎么办 退伍证名字错了怎么办 奥运怎么看 南美洲运动会第一届 出交通事故双方进行调解后一方反悔该怎么办 “江汉春风起”的出处是哪里 环境行政诉讼不履行法定职责该怎么办? 老公笨得气死人时该怎么办 美出天际的英文是什么意思? 我老公老是说我骚,我都被他气死人了 今天有个陌生手机短信说我金融骗贷 上门还有的身份证号 最下面还有个联... 让女人生气的男人靠得住吗?我家老公是一个书呆子类似人,说话气死人 网上贷款软件 我逾期了几天他们说我骗贷是咋回事 手上出现像被蚊子咬一样,又肿又红,有时候还会痒。每次出现的位置都... 腿上长了好多疙瘩,又红又痒很难受,前几天喝了啤酒怀疑酒精过敏,可是... ...大又红又疼又痒的疙瘩,绝对不是蚊子咬的,请问怎么快速有效的去除,抑 ... ...突然痒的地方抓了之后就又红又肿不像蚊子咬的. ...个电视剧叫什麽? 我就还记得的个大概:有个穷小子和一个 的女儿恋爱... 西葫芦鸡蛋饼有什么家常做法? 腿上,肚子上,手上都长了又红又痒的疙瘩,不怎么像蚊子咬得,突然一处地方... 夏普9020c手机是智能机吗?什么系统? 王菲在欧美有名吗? 电脑版微信可以用在XP系统上吗? 电影《寻龙诀:生死门》12月9日播出 Win7停止支持,还能用吗?老系统用户去还是留 寻龙之发丘天官的大蛇叫什么名字 电脑xp系统能不能用微信啊? 兰州禁养阿拉斯加吗 能不能在兰州养阿拉斯加 医生,请问为什么脸上生带状疱疹,头 带状疱疹长在脸上怎么治疗 哈士奇是大型犬还是中型犬 兰州能养吗 脸上疱疹怎么办 承揽关系是否可以构成工伤 韩剧《爱的迫降》大结局是什么 韩剧《爱的迫降》大结局猜想介绍_百度... 加工承揽关系是否能走工伤,雇佣与承揽是什么 2岁7个月宝宝上幼儿园哭闹把嗓子哭哑了,嘶哑已经有四... 玄彬哪个韩剧好看 怎样搜图片上人的名字 梦幻西游法宝为的五行属性是什么 五行属性用处介绍 idc的缩写是什么? 儿童肥胖症诊断标准是什么 工商银行本金还完了利息怎么算