JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程

1. 对象的创建

遇到new指令时

当Java虚拟机遇到一个字节码new指令时。

首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。

如果没有,那么必须执行类的加载过程(加载、检查、准备、解析、初始化)

类加载后?

类加载检查通过后,接下来虚拟机会为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定

划分内存:

  1. 如果Java堆中内存是绝对规整的,那么只需一个指针作为分界点的指示器,对象需要多少内存,就移出多少内存。我们称这种方式为指针碰撞

  2. 如果Java堆中的内存不是规整的,那么虚拟机就必须维护一个表,记录那些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表的记录,这种分配方式称为空闲列表

分配安全

在线程并发情况下,可能会出现正在给对象A分配一块内存,但指针还没来得及修改,对象B又使用了原来的指针进行分配,这就会造成内存不安全。

  1. 解决方案1:对分配内存空间的操作进行同步处理——实际上虚拟机是采用CAS配上失败重试的方式保证更新操作的原子性。

  2. 解决方案2:把内存分配的动作按照线程划分在不同空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB)

分配内存之后该怎么做?

Java虚拟机会将必要的信息存放到对象的对象头中,其中包括这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄信息等。

分配好对象头之后,对象创建才刚刚开始(Java程序的角度)

目前对象的构造函数,即Class文件中的<init>()方法还没执行,所有的字段都为默认的零值,对象需要的其他资源和状态信息也还没有按照预定的意图构造好。new指令之后会接着执行<init>()方法,按照程序员的意愿对对象进行初始化,这样一个真正可用的对象才算完全被构造出来。

2. 对象的内存布局

在HotSpot虚拟机中,对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据、对齐填充。


对象头结构

HotSpot虚拟机对象的对象头部分包括两类信息。

第一类是用于存储对象自身的运行时数据,如哈希码(HashCode) 、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方称它为“MarkWord?。MarkWord被设计成一个有着动态定义的数据结构。

        对象头的另外一部分是类型指针,即对象指向它的类型元数据的指针,Java虛拟机通过这个指针来确定该对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身,这点我们会在下一节具体讨论。此外,如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是如果数组的长度是不确定的,将无法通过元数据中的信息推断出数组的大小。


对象第二部分数据(内存)

接下来实例数据部分是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。


对象第三部分

对象的第三部分是对齐填充,这并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是任何对象的大小都必须是8字节的整数倍。对象头部分已经被精心设计成正好是8字节的倍数(1倍或者2倍),因此,如果对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。

3. 对象的访问定位

创建对象自然是为了后续使用该对象,我们的Java程序会通过栈上的reference数据来操作堆上的具体对象。由于reference类型在《Java虚拟机规范》里面只规定了它是-一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用句柄和直接指针两种:

  • 句柄::如果使用句柄访问的话,Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据类型数据各自具体的地址信息,其结构如图2-2所。

  • .如果使用直接指针访问的话,Java堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销,如图2-3所示。


两者的区别

使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访问在Java中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本,就本书讨论的主要虚拟机HotSpot而言,它主要使用第二种方式进行对象访问。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

npm安装依赖报错——npm ERR gyp verb cli的解决方法

1. 问题描述 1.1 npm安装依赖报错——npm ERR! gyp verb cli npm MARN deprecated axiosQ0.18.1: critical security vuLnerability fixed in v0.21.1. For more information, npm WARN deprecated svg001.3.2: This SVGO version is no Longer supported. upgrade to v2.x.x …

华为实训案例

案例下载 案例内包含空拓扑图、配置完整的拓扑、以及步骤脚本文档&#xff0c;可按需下载。 拓扑图 任务清单 &#xff08;一&#xff09;基础配置 根据附录1拓扑图、附录2地址规划表、附录3设备编号表&#xff0c;配置设备接口及主机名信息。 将所有终端超时时间设置为永不…

SOLIDWORKS卡顿反应慢怎么解决 慧德敏学

如果您的SOLIDWORKS软件运行缓慢或反应迟钝&#xff0c;可以尝试以下方法来提高性能和响应速度&#xff1a; 一、硬件检查与升级&#xff1a; 检查计算机硬件配置是否满足SOLIDWORKS官方推荐的要求&#xff0c;特别是CPU、内存和显卡。如果配置较低&#xff0c;考虑升级硬件以…

哨兵模式--哨兵节点的功能?

哨兵节点的主要功能有&#xff1a; 集群监控&#xff1a;监控 主、从节点的健康状况&#xff1b;自动切换主节点&#xff1a;当 Master 运行故障&#xff0c;哨兵启动自动故障恢复流程&#xff1a;从 slave 中选择一台作为新 master。通知&#xff1a;让 slave 执行 replicaof…

社交风潮塑造者:探索用户在Facebook的影响力

在当今数字化社会中&#xff0c;Facebook不仅是人们社交互动的主要平台&#xff0c;更是塑造社交风潮和文化趋势的重要力量。本文将从另一个角度深入探讨用户在Facebook上的影响力&#xff0c;探索其如何通过个人行为和互动&#xff0c;影响和改变社会的各个方面。 个人表达和内…

Cryptographic algorithms—(Green-Book)加密算法

Cryptographic algorithms—加密算法 9.2.3 加密算法9.2.3.1 概述9.2.3.2 哈希函数9.2.3.3 对称密钥算法9.2.3.3.1 概述9.2.3.3.2 加密和解密9.2.3.3.3 高级加密标准9.2.3.3.4 加密操作模式9.2.3.3.5 消息认证码9.2.3.3.6 密钥包装9.2.3.3.7 Galois/Counter Mode9.2.3.3.7.1 概…

Python中相关软件安装

1. python安装 1.下载地址 https://www.python.org/downloads/2.选择安装版本 1. Anaconda安装 安装地址 -- 清华大学镜像站点 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/查看anaconda是否安装成功 2.conda安装好后&#xff0c;将镜像源修改为清华大学的镜像…

音频Balance源码总结

音频Balance源码总结 何为音频Balance&#xff1f; 顾名思义&#xff0c;Balance及平衡&#xff0c;平衡也就是涉及多方&#xff0c;音频左右甚至四通道&#xff0c;调节所有通道的音量比&#xff0c;使用户在空间内听到各个通道的音频大小不一&#xff0c;好似置身于真实环境…

vue 组件批量删除

element ui table表格中前面这个勾选框 对应 type"selection" 属性&#xff0c;绑定事件时selection-change,当你勾选全面的框时就会触发selection-change 对应的事件 绑定事件里面这样定义方法时&#xff0c;这个val 就是选中的时候那一行的数据&#xff0c;如下图…

【数据分享】《中国县城建设统计年鉴》2015-2022

而今天要免费分享的数据就是2015-2022年间出版的《中国县城建设统计年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 在中国快速城镇化的进程中&#xff0c;县城作为连接城市与乡村的重要节点&#xff0c;其建设与发展受到了广泛关注…

高性价比 ESP32 网络收音机:OLED 显示+编码器控制 (源码开源)

摘要: 本文将详细介绍如何使用 ESP32 开发板制作一个功能完备的网络收音机。我们将涵盖硬件选择、软件架构、网络连接、音频流解码、用户界面设计等方面&#xff0c;并提供完整的代码示例和详细的解释&#xff0c;帮助您轻松构建自己的网络收音机。 关键词: ESP32, 网络收音机…

免交互和嵌入执行模式

目录 概念 语法格式 统计行数 赋值变量 修改密码​编辑往文件里添加内容 ​编辑​编辑引入变量 整体赋值​编辑 加引号不赋值变量 expect实现免交互 免交互设置密码 免交互切换用户 嵌入执行模式 添加用户并免交互设置密码 免交互登录 传参实现ssh 练习 概念 …

梦想CAD二次开发

1.mxdraw简介 mxdraw是一个HTML5 Canvas JavaScript框架&#xff0c;它在THREE.js的基础上扩展开发&#xff0c;为用户提供了一套在前端绘图更为方便&#xff0c;快捷&#xff0c;高效率的解决方案&#xff0c;mxdraw的实质为一个前端二维绘图平台。你可以使用mxdraw在画布上绘…

复盘|接口自动化测试框架建设的经验与教训

为什么选择这个话题&#xff1f; 一是发现很多“点工”在转型迷茫期都会问一些自动化测试相关的问题&#xff0c;可以说自动化测试是“点工”升级的必经之路&#xff1b;二是Google一下接口自动化测试&#xff0c;你会发现很多自动化测试框架相关的文章&#xff0c;但是大部分…

VBA 批量变换文件名

1. 页面布局 在“main”Sheet中按照下面的格式编辑。 2. 实现代码 Private wsMain As Worksheet Private intIdx As LongPrivate Sub getExcelBookList(strPath As String)Dim fso As ObjectDim objFile As ObjectDim objFolder As ObjectSet fso CreateObject("Script…

CAN和CANFD数据写入.asc文件的dll

因为工作需要&#xff0c;需要做一些硬件不是CANoe的上位机&#xff08;比如说周立功CAN,NI-CAN&#xff09;&#xff0c;上位机需要有记录数据的功能&#xff0c;所以用Qt制作了一个记录数据的dll&#xff0c;方便重复使用&#xff08;因为有的客户指定了编程软件&#xff0c;…

Redis主从复制、哨兵以及Cluster集群

1.Redis高可用 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;除了保证提供…

加密教程:pdf怎么加密?7个pdf加密技巧任你选(图文详解)

pdf作为一种便携式文档&#xff0c;是展示内容的首选格式&#xff0c;目前也已广泛应用于交换和分享重要等温&#xff0c;例如内部报告、人力资源文件&#xff0c;以及商业提案等包含敏感信息的文档。然而&#xff0c;在如今的数字化时代&#xff0c;随着越来越多的企业将其文档…

capitalize()方法——字符串首字母转换为大写

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 capitalize()方法用于将字符串的首字母转换为大写&#xff0c;其他字母为小写&#xff0c;例如图1所示的效果。 图1 字符串首字母大写效果…

动手实现一个可发送短信随机密码的高安全性用户密码系统

动手实现一个可发送短信随机密码的高安全性用户密码系统 1、背景2、设计3、代码实现3.1、首先先看一下ThreadSpecificSecureRandom组件代码实现,如图所示3.2、调用nextInt的UserPasswordSystemManager组件的代码实现3.3、UserPasswordSystemManager组件所提供的方法,请看下图…