JVM 之对象的结构与创建

1.对象的创建

1.1类加载
        当Java 虚拟机遇到一条字节码 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到 一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那 必须先执行相应的类加载过。
1.2划分空间
(1)假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump The Pointer)
(2)假设Java堆中的内存并不是规整的,已被使用的内存和空闲的内存相互交错在一起,那
就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分 配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称 为“ 空闲列表 Free List )。选择哪种分配方式由 Java 堆是否规整决定,而 Java 堆是否规整又由所采用 的垃圾收集器是否带有空间压缩整理(Compact )的能力决定。
保证对象创建的线程安全性

(1) 采用CAS+失败重试保证更新操作证的原子性

(2)把内存分配动作按照线程划分在不同空间中进行。在堆中为每个内存分配一小块空间,称为本地线程分配缓冲(TLAB)。线程分配内存时,在自己的TLAB上分配,当TLAB使用完时,使用同步锁。

1.3 赋零值
        虚拟机必须将分配到的内存空间(但不包括对象头)都初始化为零值,如果使用了TLAB 的话,这一项工作也可以提前至 TLAB 分配时顺便进行。这步操作保证了对象的实例字段 在Java 代码中可以不赋初始值就直接使用,使程序能访问到这些字段的数据类型所对应的零值。
1.4设置对象头
        接下来,Java 虚拟机还要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码(实际上对象的哈希码会延后到真正调用Object::hashCode() 方法时才计算)、对象的GC 分代年龄等信息。这些信息存放在对象的对象头( Object Header )之中。根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
1.5 执行<init>()方法
        在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了。但是从Java 程序的视角看来,对象创建才刚刚开始—— 构造函数,即 Class 文件中的 <init>() 方法还没有执行,所有的字段都 为默认的零值,对象需要的其他资源和状态信息也还没有按照预定的意图构造好。一般来说(由字节码流中new 指令后面是否跟随 invokespecial 指令所决定, Java 编译器会在遇到 new 关键字的地方同时生成 这两条字节码指令,但如果直接通过其他方式产生的则不一定如此),new 指令之后会接着执行 <init> ()方法,按照程序员的意愿对对象进行初始化,这样一个真正可用的对象才算完全被构造出来。

2.对象的内存布局

        对象在堆内存中的存储布局可以划分为三个部分:对象头(Header )、实例数据(Instance Data )和对齐填充( Padding )。
2.1 对象头
第一部分:
        是用于存储对象自身的运行时数据,如哈希码(HashCode)、 GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32个比特和64个比特,官方称它为“Mark Word”。
第二部分:
        对象头的另外一部分是类型指针,即对象指向它的类型元数据的指针,有一块用于记录数组长度的数据。
2.2 实例数据
        是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。
2.3 对齐填充
        对齐填充,这并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作 用。由于HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍,换句话说就是 任何对象的大小都必须是8 字节的整数倍。对象头部分已经被精心设计成正好是 8 字节的倍数( 1 倍或者 2倍),因此,如果对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。

3.对象的访问定位

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。
主流的访问方式主要有使用句柄和直接指针两种:
        (1)如果使用句柄访问的话,Java 堆中将可能会划分出一块内存来作为句柄池, reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息。
        (2)如果使用直接指针访问的话,Java 堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference 中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销。
        使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访问在Java 中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本。

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

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

相关文章

Python MySQL 教程

Python MySQL 教程 引言 Python 是一种广泛使用的高级编程语言,以其简洁明了的语法和强大的功能而闻名。MySQL 是一种流行的开源关系数据库管理系统 (RDBMS),广泛用于各种应用程序,包括数据密集型 Web 应用程序。Python MySQL 教程将指导您如何使用 Python 语言与 MySQL 数…

C# .net6使用Hangfire

首先我们先来了解什么是Hangfire&#xff1f; Hangfire 是一个用于 .NET 的任务调度库&#xff0c;允许你在后台运行任务&#xff0c;而不需要依赖外部的任务队列服务或复杂的基础设施。它简化了后台任务的创建、调度和管理过程&#xff0c;使得在 .NET 应用程序中处理长期运行…

flutter Android端权限

flutter 中权限请求path_provider Android 6.0 - 10.0 (API level 23 - 29)Android 11 (API level 30)具体实现示例注意事项 在 Flutter 中使用 path_provider 插件获取除本应用外所有的 PDF 文件&#xff0c;对于不同的 Android 版本&#xff08;从 Android 6.0 到 Android 14…

我不是一个人在战斗

这也是一个老生常谈的话题&#xff0c;但很多人还是出不出单兵作战的怪圈&#xff0c;不断让单兵作战的孤独感、团队协作的无助感困惑自己&#xff0c;困惑整个团队&#xff0c;造成心气一直不高&#xff0c;严重影响工作效率。对此我还是坚持去年的观点&#xff1a;坚持宽松、…

【系统架构设计】操作系统(一)

操作系统&#xff08;一&#xff09; 操作系统的类型和结构操作系统基本原理进程管理进程三态模型挂起状态进程互斥 / 进程同步前趋图进程调度死锁 存储管理设备管理文件管理作业管理 操作系统原理的关键在于“一个观点、两条线索”&#xff1a;一个观点是以资源管理的观点来定…

简谈设计模式之代理模式

代理模式是一种结构型设计模式, 主要用于为其他对象提供一种代理, 以控制对这个对象的访问. 代理模式可以在不修改目标对象的前提下, 通过代理对象在访问目标对象之前或之后增加额外的操作 代理模式结构 抽象主题: 定义了真实主题和代理的共同接口, 这样客户端就可以通过接口…

【算法笔记自学】第 9 章 提高篇(3)——数据结构专题(2)

9.1树与二叉树 #include <cstdio>int main() {int n, m;scanf("%d%d", &n, &m);printf(n m 1 ? "Yes" : "No");return 0; } 9.2二叉树的遍历 #include <cstdio> #include <vector> using namespace std;const int…

Java毕业设计 基于SSM vue电影订票系统小程序 微信小程序

Java毕业设计 基于SSM vue电影订票系统小程序 微信小程序 SSM 电影订票系统小程序 功能介绍 用户 登录 注册 忘记密码 首页 图片轮播 电影信息 电影详情 评论 收藏 预订 电影资讯 资讯详情 用户信息修改 电影评价 我的收藏管理 用户充值 在线客服 我的订单 管理员 登录 个人…

不遵守全局主键配置【PGSQL】

<selectKey keyProperty"id" resultType"java.lang.Long" order"BEFORE"> SELECT nextval(ft.id2_seq::regclass) </selectKey> 这段 XML 配置中的 <selectKey> 标签是 MyBatis 中用来生成主键的关键部分。让我解释一下每个…

SpringCloud集成kafka集群

目录 1.引入kafka依赖 2.在yml文件配置配置kafka连接 3.注入KafkaTemplate模版 4.创建kafka消息监听和消费端 5.搭建kafka集群 5.1 下载 kafka Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/downloads.html 5.2 在config目录下做…

java导出word实现

参考&#xff1a;Poi-tl Documentation

NaiveUI与ElementUI 比较分析

前言 在前端开发的广阔领域中&#xff0c;Vue.js作为最流行的前端框架之一&#xff0c;为开发者提供了丰富的组件库&#xff0c;其中NaiveUI和ElementUI是两个备受瞩目的选择。本文将深入分析这两个组件库的特点、优劣势以及适用场景&#xff0c;帮助开发者在项目中做出更合适…

全渠道AI智能商品管理软件平台 助力零售品牌占领技术高地

关于7thonline第七在线 1999年创立于纽约&#xff0c;7thonline第七在线全渠道AI智能商品管理平台&#xff0c;以先进的数学算法模型、人工智能和机器学习技术为核心驱动力&#xff0c;融合了众多零售商品管理的卓越实践经验&#xff0c;精心打造出一套深度适配零售业务场景的自…

[每周一更]-(第105期):SSL证书过期后引发的DNS缓存问题

问题回顾&#xff1a; ​ 上班路上收到ZeroSSL邮件通知我们清点项目的SSL证书到期了&#xff0c;到公司还是登录网址查看信息&#xff0c;一看果然是7.10也就是今天到期&#xff0c;开始看下acme.sh的定制任务为何没生效&#xff0c;一看crontab脚本&#xff0c;日志任务丢垃圾…

tomcat和nginx实现动静分离

访问nginx就是静态页面&#xff0c;nginx代理index.jsp可以访问tomcat的动态页面。 实验 1、设备以及IP地址 nginx1 192.168.10.41 tomcat1 192.168.10.51 tomcat2 192.168.10.52 2、tomcat1 的配置 创建动态页面 cd /usr/local/tomcat/webapps 创建一个目录作为一个ser…

复现ORB3-YOLO8项目记录

文章目录 1.编译错误1.1 错误11.2 错误21.3 错误31.4 错误4 1.编译错误 首先ORB-SLAM相关项目已经写过很多篇博客了&#xff0c;从ORB-SLAM2怎么运行&#xff0c;再到现在的项目。关于环境已经不想多说了 1.1 错误1 – DEPENDENCY_LIBS : /home/lvslam/ORB3-YOLO8/Thirdparty…

2024年C#优秀实用的类库推荐

简介 在软件开发领域&#xff0c;随着技术的不断进步和项目的复杂化&#xff0c;使用高质量的类库来加速开发过程、减少错误并提高代码质量变得至关重要。C# 作为一款功能强大的编程语言&#xff0c;拥有众多优秀的类库供开发者选择。本文旨在为您推荐一些在2024年备受推崇的C…

Feature Alignment and Uniformity for Test Time Adaptation--论文笔记

论文笔记 资料 1.代码地址 https://github.com/SakurajimaMaiii/TSD 2.论文地址 https://arxiv.org/abs/2303.10902 3.数据集地址 论文摘要的翻译 TTA在接收训练分布外的测试域样本时对深度神经网络进行自适应。在这样设置下&#xff0c;模型只能访问在线未标记的测试样…

昇思MindSpore学习总结十五 ——基于Mindspore 实现BERT对话情绪识别

1、环境配置 根据实际情况&#xff0c;选择合适版本。 %%capture captured_output # 实验环境已经预装了mindspore2.2.14&#xff0c;如需更换mindspore版本&#xff0c;可更改下面mindspore的版本号 !pip uninstall mindspore -y !pip install -i https://pypi.mirrors.ustc…

MYSQL--第七次作业

MYSQL–第七次作业 在product表上创建三个触发器。每次激活触发器后&#xff0c;都会更新operate表。product表和表的内容如下 Product表内容 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 产品编号 Int(10) 是 否 是 是 否 Name …