Java对象结构

Java 对象(Object 实例)结构包括三部分:对象头、对象体、对齐字节。

Object的三个部分 

对象头包括三个字段,第一个字段叫做 Mark Word(标记字),用于存储自身运行时的数据 例如 GC 标志位、哈希码、锁状态等信息。

第二个字段叫做 Class Pointer(类对象指针),用于存放方法区 Class 对象的地址,虚拟机通过这个指针来确定这个对象是哪个类的实例。

第二个字段叫做 Array Length(数组长度)。如果对象是一个 Java 数组,那么此字段必须有, 用于记录数组长度的数据;如果对象不是一个 Java 数组,那么此字段不存在,所以这是一个可选字段。

对象体包含了对象的实例变量(成员变量)。用于成员属性值,包括父类的成员属性值。这部分内存按 4 字节对齐。

对齐字节也叫做填充对齐,其作用是用来保证 Java 对象在所占内存字节数为 8 的倍数(8N bytes)。HotSpot VM 的内存管理要求对象起始地址必须是 8 字节的整数倍。对象头本身是 8 的倍数,当对象的实例变量数据不是 8 的倍数,便需要填充数据来保证 8 字节的对齐。

对象结构中的核心字段

  • Mark Word(标记字)字段主要用来表示对象的线程锁状态,另外还可以用来配合 GC、 存放该对象的 hashCode。

  • Class Pointer(类对象指针)字段是一个指向方法区中 Class 信息的指针,意味着该对象可随时知道自己是哪个 Class 的实例。

  • Array Length(数组长度)字段也占用 32 位(在 32 位 JVM 中)的字节,这是可选的, 只有当本对象是一个数组对象时才会有这个部分。

  • 对象体用于保存对象属性值,是对象的主体部分,占用的内存空间大小取决于对象的属性数量和类型。

  • 对齐字节并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。当对象实例数据部分没有对齐(8 字节的整数倍)时,就需要通过对齐填充来补全。

对象结构中的字段长度

Mark Word、Class Pointer、Array Length 等字段的长度,都与 JVM 的位数有关。Mark Word 的长度为 JVM 的一个 Word(字)大小,也就是说 32 位 JVM 的 Mark Word 为 32 位,64 位 JVM 为 64 位。Class Pointer(类对象指针)字段的长度也为 JVM 的一个 Word(字)大小,即 32 位的 JVM为32位,64位的JVM为64位。

所以,在 32 位 JVM 虚拟机中,Mark Word 和 Class Pointer 这两部分都是 32 位的;在 64 位 JVM 虚拟机中,Mark Word 和 Class Pointer 这两部分都是 64 位的。

对于对象指针而言,如果 JVM 中对象数量过多,使用 64 位的指针将浪费大量内存,通过简单统计,64 位的 JVM 将会比 32 位的 JVM 多耗费 50%的内存。为了节约内存可以使用选项 +UseCompressedOops 开启指针压缩。选项 UseCompressedOops 中的 Oop 部分为 Ordinary object pointer 普通对象指针的缩写。

如果开启 UseCompressedOops 选项,以下类型的指针将从 64 位压缩至 32 位:

  • Class 对象的属性指针(即静态变量)

  • Object 对象的属性指针(即成员变量)

  • 普通对象数组的元素指针

当然,也不是所有的指针都会压缩,一些特殊类型的指针不会压缩,比如指向 PermGen(永久代)的 Class 对象指针(JDK8 中指向元空间的 Class 对象指针)、本地变量、堆栈元素、入参、返回值和 NULL 指针等。

如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度(Array Length 字段)。Array Length 字段的长度也随着 JVM 架构的不同而不同:32 位的 JVM 上,长度为 32 位; 64 位 JVM 则为 64 位。64 位 JVM 如果开启了 Oop 对象的指针压缩,Array Length 字段的长度也将由64位压缩至32位。

Mark Word的结构信息

Java 内置锁的涉及到很多重要信息,这些都存放在对象结构中,并且是存放于对象头的 Mark Word 字段中。Mark Word 的位长度为 JVM 的一个 Word 大小,也就是说 32 位 JVM 的 Mark word 为 32 位,64 位 JVM 为 64 位。Mark Word 的位长度不会受到 Oop 对象指针压缩选项的影响。

Java 内置锁的状态总共有四种,级别由低到高依次为:无锁,偏向锁,轻量级锁,重量级锁。

其实在 JDK1.6 之前,Java 内置锁还是一个重量级锁,是一个效率比较低下的锁,在 JDK1.6 之 后,JVM 为了提高锁的获取与释放效率,对 synchronized 的实现进行了优化,引入了偏向锁、轻 量级锁的实现,从此以后 Java 内置锁的状态就有了四种(无锁、偏向锁、轻量级锁、重量级锁), 并且四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,即不可降级,也就是说只能进 行锁升级(从低级别到高级别)。

64位锁结构信息

lock:锁状态标记位

占 2 个二进制位,由于希望用尽可能少的二进制位表示尽可能多 的信息,所以设置了 lock 标记。该标记的值不同,整个 Mark Word 表示的含义不同。

biased_lock

对象是否启用偏向锁标记,只占 1 个二进制位。为 1 时表示对象启用偏向锁,为 0 时表示对象没有偏向锁。

lock 和 biased_lock 两个标记位组合在一起,共同表示 Object 实例处于什么样的锁状态。二者组合的含义如下:

age

4位的 Java 对象分代年龄。在 GC 中,如果对象在 Survivor 区复制一次,年龄增加 1。当对象达到设定的阈值时,将会晋升到老年代。默认情况下,并行 GC 的年龄阈值为 15,并发 GC 的年龄阈值为 6。由于 age 只有 4 位,所以最大值为 15,这就是-XX:MaxTenuringThreshold 选 项最大值为 15 的原因。

identity_hashcode

31 位的对象标识 HashCode(哈希码),采用延迟加载技术,当调用 Object.hashCode()方法或者 System.identityHashCode() 方法计算对象的 HashCode 后,其结果将 被写到该对象头中。当对象被锁定时,该值会移动到 Monitor(监视器)中。

thread

54 位的线程 ID 值,为持有偏向锁的线程 ID。

epoch

偏向时间戳。

ptr_to_lock_record

占 62 位,在轻量级锁的状态下,指向栈帧中锁记录的指针。

ptr_to_heavyweight_monitor

占 62 位,在重量级锁的状态下,指向对象监视器 Monitor的指针。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/257414.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CEC2013(python):五种算法(HHO、WOA、GWO、DBO、PSO)求解CEC2013(python代码)

一、五种算法简介 1、哈里斯鹰优化算法HHO 2、鲸鱼优化算法WOA 3、灰狼优化算法GWO 4、蜣螂优化算法DBO 5、粒子群优化算法PSO 二、5种算法求解CEC2013 (1)CEC2013简介 参考文献: [1] Liang J J , Qu B Y , Suganthan P N , et al. P…

设计模式(三)-结构型模式(5)-外观模式

一、为何需要外观模式(Facade)? 要实现一个大功能,我们需要将它拆分成多个子系统。然后每个子系统所实现的功能,就由一个称为外观的高层功能模块来调用。这种设计方式就称为外观模式。该模式在开发时常常被使用过,所…

翻译: LLMs大语言模型影响到高工资的的白领知识工作者 加速各行各业的自动化潜力 Automation potential across sectors

我们已经探讨了生成人工智能可能对您的工作有用,也讨论了分析其对企业的影响。现在,让我们拉远镜头,看看它对不同公司的工作角色以及对不同行业部门的影响。这个视频的结果对特定企业可能不那么直接可行,但也许这会帮助您思考并尝…

文件包含的提升刷题

上一篇文章:一篇文章带你入门文件包含-CSDN博客 已经开始入门了文件包含,那现在开始拔高提升刷题! 1. 拿到题目后啥也没有,所以也不知道要读取啥文件,那就查看源代码。 直接看if的条件就可以知道一定要设置cookie&a…

【C++】模板--函数模板.类模板

目录 一 函数模板 1 概念 2 函数模板格式 3 函数模板的原理 4 模板参数的匹配原则 1 多个模板参数 2 非模板函数和同名的函数模板 5 函数模板实例化 1. 隐式实例化 2. 显式实例化 二 类模板 1 类模板定义格式 2 类模板实例化 3 细节 一 函数模板 1 概念 函数模…

Shell三剑客:sed(示例)

一、删除配置文件中#号注释 [rootlocalhost ~]# sed -ri /^#/d /etc/vsftpd/vsftpd.conf [rootlocalhost ~]# vim /etc/vsftpd/vsftpd.conf #查看 二、 修改文件 [rootlocalhost ~]# sed -ri $a chroot_local_userYES /etc/vsftpd/vsftpd.conf [rootlocalhost ~]# sed …

Markdown 使用笔记

文章目录 Part.I IntroductionChap.I 传送门 Part.II 语法Chap.I 基础语法Chap.II 字体控制Chap.III 超链接 & 脚注Chap.IV 一些小妙招 Part.III 在线 Markdown 编辑工具Chap.I StackEditChap.II HedgeDoc Reference Part.I Introduction Markdown是一种轻量级标记语言&am…

excel该如何实现生成条形码/二维码?

如何在Excel中制作条形码/二维码? 1.首先,打开电脑上的Excel。进入后,在上方菜单栏中找到并点击“开发工具”。如果没有找到开发工具,就先点击“文件”,在弹出菜单中再点击“选项”。 2.打开Excel选项窗口后&#xff0…

多维时序 | MATLAB实现WOA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现WOA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现WOA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现WOA-CNN-LST…

【算法Hot100系列】删除链表的倒数第 N 个结点

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Adaptive IBC :异构链互操作性的颠覆者

2024年第一季度,隐私协议 Secret Network 将会使用 Octopus Network 基于 Adaptive IBC 技术路线开发的 NEAR IBC,实现与 NEAR Protocol 之间将会实现首次跨链交互,这同样是 Cosmos 生态与 NEAR 之间的首次连接。整个加密世界正在成为一个越来…

【Spring学习笔记】Spring 核心容器

Spring学习——核心容器 Spring介绍初识SpringSpring Framework系统架构图Spring Framework学习路线核心概念IoC入门案例IoC入门案例思路分析IoC入门案例实现Ioc入门案例(XML版) DI入门案例DI入门案例思路分析DI入门案例实现 bean配置bean基础配置bean别…

JAVA 中的 SPI 机制,从原理、现有框架中的使用以及自定义实现 SPI 机制使用来深入了解 SPI 机制

首先介绍 SPI 是什么 SPI 机制在框架中的使用 SPI 机制使用约定MySQL 驱动实现 SPI 机制示例 最后自己动手实现 SPI 机制使用示例 文章链接,点击跳转

springAop有哪五种通知类型?可根据图标查看!

Spring AOP的通知类型有以下几种(后面是图标变化): 1.Before通知: 在目标方法执行前执行。 上白下红,方法前执行。 2.After通知: 在目标方法执行后(无论是否发生异常)执行。 图标…

Python Pandas DataFrame对象数据的排序(第13讲)【sort_values()rank()】

Python Pandas DataFrame对象数据的排序(第13讲)【sort_values()&rank()】         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹…

带大家做一个,易上手的家常糖醋排骨

先把排骨切块 你可以在卖的时候直接让卖排骨的给你切成块 然后清水冲洗两次 然后 将排骨放入锅中 用清水煮一下 等排骨开始变颜色,直接捞出来 水倒掉 排骨和锅都用清水冲一下,这样排骨中的血水就基本清除掉了 然后是 糖醋排骨调料小公式 一勺料酒 两勺…

加油站“变身”快充站,探讨充电新模式——安科瑞 顾烊宇

摘要:新能源汽车规模化发展的同时,充电不便利的痛点愈发明显。在未来的新能源汽车行业发展当中,充电的矛盾要远远大于造车的矛盾,解决好充电的问题成为电动汽车行业发展的一个突出问题。解决充电补能问题,重要的方式之…

【算法与数据结构】53、LeetCode最大子数组和

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:程序一共两个变量,一个result一个count。result用来记录最终的结果,count记录当…

Python编辑器推荐:2023 年最值得使用的五款Python编辑器

一、Visual Studio Code Visual Studio Code 是一款由微软开发的开源代码编辑器。并且支持多种编程语言,包括 Python、C等。 MySQL使用教程掌握MySQL使用技巧,轻松管理数据!本教程深入浅出地介绍如何使用MySQL,涵盖从安装&#x…

代码评审——静态map初始化并赋值问题

问题描述&#xff1a; 在程序开发过程中&#xff0c;经常使用到Map来进行数据的处理。但在开发过程中&#xff0c;当使用静态Map时&#xff0c;初始化数据会存在一些危险的情况。 可以参考如下示例代码&#xff1a; public static Map<String,String> staticMap new H…