JVM对象实例化详解

news/2024/5/6 12:30:40/文章来源:https://blog.csdn.net/u011837804/article/details/129268578

1、对象创建方式你知道几种呢?

  • new:最常见的方式、Xxx的静态方法,XxxBuilder/XxxFactory的静态方法

  • Class的newInstance方法:反射的方式,只能调用空参的构造器,权限必须是public

  • Constructor的newInstance(XXX):反射的方式,可以调用空参、带参的构造器,权限没有要求

  • 使用clone():不调用任何的构造器,要求当前的类需要实现Cloneable接口,实现clone()

  • 使用序列化:从文件中、从网络中获取一个对象的二进制流

  • 第三方库 Objenesis

2、创建对象的步骤

2.1、 判断对象对应的类是否加载、链接、初始化

虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace(jdk1.8)的常量池中(方法区中)定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载,解析和初始化(即判断类元信息是否存在)。

如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader + 包名 + 类名为key进行查找对应的 .class文件;

  • 如果没有找到文件,则抛出ClassNotFoundException异常

  • 如果找到,则进行类加载,并生成对应的Class对象

2.2、为对象分配内存

首先计算对象占用空间的大小,接着在堆中划分一块内存给新对象。如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节大小

如果内存规整:虚拟机将采用的是指针碰撞法(Bump The Point)来为对象分配内存。

  • 意思是所有用过的内存在一边,空闲的内存放另外一边,中间放着一个指针作为分界点的指示器,分配内存就仅仅是把指针指向空闲那边挪动一段与对象大小相等的距离罢了。如果垃圾收集器选择的是Serial ,ParNew这种基于压缩算法的,虚拟机采用这种分配方式。一般使用带Compact(整理)过程的收集器时,使用指针碰撞。

如果内存不规整:虚拟机需要维护一个空闲列表(Free List)来为对象分配内存。

  • 已使用的内存和未使用的内存相互交错,那么虚拟机将采用的是空闲列表来为对象分配内存。意思是虚拟机维护了一个列表,记录上那些内存块是可用的,再分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的内容。

选择哪种分配方式由Java堆是否规整所决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

2.3、处理并发问题

  • 采用CAS失败重试、区域加锁保证更新的原子性

  • 每个线程预先分配一块TLAB:通过设置 -XX:+UseTLAB参数来设定

2.4、初始化分配到的内存

所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用

2.5、 设置对象的对象头

将对象的所属类(即类的元数据信息)、对象的HashCode和对象的GC信息、锁信息等数据存储在对象的对象头中。这个过程的具体设置方式取决于JVM实现。

2.6、执行init方法进行初始化

也就是执行构造函数+非静态代码块的过程+属性的显示赋值

在Java程序的视角看来,初始化才正式开始。初始化成员变量,执行实例化代码块,调用类的构造方法,并把堆内对象的首地址赋值给引用变量。

因此一般来说(由字节码中跟随invokespecial指令所决定),new指令之后会接着就是执行方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完成创建出来。

给对象属性赋值的操作

  • 属性的默认初始化

  • 显式初始化

  • 代码块中初始化

  • 构造器中初始化

3、对象内存布局

3.1、对象头(Header)

对象头包含了两部分,分别是运行时元数据(Mark Word)和类型指针。如果是数组,还需要记录数组的长度

3.1.1、运行时元数据

  • 哈希值(HashCode)

  • GC分代年龄

  • 锁状态标志

  • 线程持有的锁

  • 偏向线程ID

  • 翩向时间戳

3.1.2、类型指针

指向类元数据InstanceKlass,确定该对象所属的类型。

3.2、实例数据(Instance Data)

它是对象真正存储的有效信息,包括程序代码中定义的各种类型的字段(包括从父类继承下来的和本身拥有的字段)

  • 相同宽度的字段总是被分配在一起

  • 父类中定义的变量会出现在子类之前

  • 如果CompactFields参数为true(默认为true):子类的窄变量可能插入到父类变量的空隙

3.3、 对齐填充(Padding)

不是必须的,也没有特别的含义,仅仅起到占位符的作用

3.4、举例

public class Customer{int id = 1001;String name;Account acct;{name = "匿名客户";}public Customer() {acct = new Account();}
}public class CustomerTest{public static void main(string[] args){Customer cust=new Customer();}
}

4、对象的访问定位

JVM是如何通过栈帧中的对象引用访问到其内部的对象实例呢?

4.1、对象访问方式之句柄访问

reference中存储稳定句柄地址,对象被移动(垃圾收集时移动对象很普遍)时只会改变句柄中实例数据指针即可,reference本身不需要被修改。

4.2、对象访问之直接指针(Hotspot采用)

直接指针是局部变量表中的引用,直接指向堆中的实例,在对象实例中有类型指针,指向的是方法区中的对象类型数据。

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

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

相关文章

【女士,房间墙上凿个洞,看你在干嘛~】安全攻防内网渗透-绕过防火墙和安全检测,搭建DNS隐蔽隧道

作者:Eason_LYC 悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。 一个人的价值,在于他所拥有的。所以可以不学无术,但不能一无所有! 技术领域:WEB安全、网络攻防 关注WEB安全、网络攻防。…

将vue-devtools打包成edge插件

文章目录一、从github拉vue-devtools源码二、用npm安装yarn三、使用yarn安装并编译源码四、将vue-devtools打包成edge插件五、离线安装edge插件一、从github拉vue-devtools源码 目前最新的版本是v6.5.0,地址:https://github.com/vuejs/devtools 二、用n…

深度学习被你忽略的细节系列篇——Softmax、LogSumExp和Sigmoid

平时我们基本用pytorch或者tensorflow框架时,基本对特别底层的函数实现关注不多,仅限于知道公式的原理。但是很多大佬往往自己会实现一些源码(比如ListNet复现),在看这些源码时,经常出现各种有点难以理解的代码,本来很…

教你如何搭建设备-巡检管理系统,demo可分享

1、简介1.1、案例简介本文将介绍,如何搭建设备-巡检管理。1.2、应用场景设备管理员进行制定设备巡检时间/内容计划、记录设备巡检信息、可以查看今日待巡检设备。2、设置方法2.1、表单搭建1)新建表单【设备档案-履历表】,字段设置如下&#x…

安卓手机当旁路网关

一、安卓shell调试工具下载【电脑版下载地址】安卓adb调试工具,包含MAC苹果、Windows和Linux 三种版【手机版下载地址Termux】下载地址:https://github.com/termux/termux-app/releases如果不懂下载哪个版本,可以直接下载通用版:t…

【unity3d】rts engine 5 设置集结点;放置建筑

一 接上回新建建筑,设置生产单位,现在设置集结点 1 进入建筑预制体,add component 添加 rallypoint setting target 页面,设置面板按钮,音频 resource dead是可设置在耗尽的资源上,下一个是自动寻找附近同…

QT打包的两种方式

QT打包的两种方式: 一个是QT5自带的windeployqt(不需要下载安装),它可以找到程序(exe)用到的所有库文件,并且都拷贝到exe程序的当前文件。此时打包的exe较小,需要和拷贝进来的文件放…

Modbus网关在锂电池干燥箱的应用

在锂离子电池生产过程中,将正负极片辊压绕卷再放入电池盒之后,须对锂电池电芯极组进行烘烤干燥。相信大家也了解水分对锂电池的性能影响是很大的,需要注液前在装配车间将锂离子电池电芯内部的水分去除,以免影响锂电池质量。在锂电…

在 The Sandbox 中以全新的 Rabbids 体验庆祝兔年!

育碧(Ubisoft) 和 The Sandbox 联手为你们带来终极的农历新年体验! 穿戴上你们新鲜出炉的 Rabbids 人物化身来参加派对吧,保证震撼整个元宇宙!这个全新体验为 Rabbids 人物化身持有者专属。没有获得 Rabbids 人物化身吗?不要担心&…

你知道Java中的JCP, JEP, JLS, JSR是什么意思吗?

目录 一、JCP 二、JSR 三、JLS 四、JEP 公众号:MCNU云原生,欢迎微信搜索关注,更多干货,及时掌握。 JCP, JEP, JLS, JSR这些概念是Java社区中的一些概念,但是没有没有经常关注社区的童鞋们未必知道这些缩写所代表的…

围棋

围棋 规则 棋盘 围棋使用矩形格状棋盘及黑白二色圆形棋子进行对弈,正规棋盘上有纵横各19条线段,361个交叉点。 基本下法 1.对局双方各执一色棋子,黑先白后,交替下子,每次只能下一子。 2.棋子…

Go 实现 AOI 区域视野管理

在游戏中,场景里存在大量的物体.如果我们把所有物体的变化都广播给玩家.那客户端很难承受这么大的压力.因此我们肯定会做优化.把不必要的信息过滤掉.如只关心玩家视野所看到的.减轻客户端的压力,给玩家更流畅的体验. 优化的思路一般是: 第一个是尽量降低向客户端同步对象的数量…

为什么FPGA在深度学习领域有着得天独厚的优势?

01 FPGA在深度学习领域有哪些优势 FPGA(Field-Programmable Gate Array)是一种灵活的可编程硬件设备,它在深度学习应用领域中具有许多优势。 首先,FPGA具有非常高的并行性。在深度学习中,许多计算都可以并行化&…

“数字档案室测评”相关参考依据梳理

数字档案室建设无疑比数字档案馆建设应用范围更为广泛,涉及的单位类型和专业领域也更多。这一点从国家档案局的机构设置上也可以看出端倪: 国家档案局两个内设业务指导司中,档案馆(室)业务指导司主要针对档案馆和机关档案室,而经济…

施工机械设备群远程在线监控管理系统

一、项目背景 在加强基础设施建设等一系列政策的牵引下,我国工程机械设备市场连续保持强劲增长势头,伴随国内中高端机械设备公司业务的不断扩展,施工大型机械设备的应用率不断提高,铁路施工特别是架桥机作业过程被认为是一个极易出…

Windows搭建机器学习环境

一、环境介绍Anaconda:Anaconda offers the easiest way to perform Python/R data science and machine learning on a single machine. Start working with thousands of open-source packages and libraries today.Anaconda包括Conda、Python以及一大堆安装好的工…

边缘计算开源项目解读——kubeedge mappers实现

0 背景 本文重点解读kubeedge项目中的mapper模块。该模块位于kubeedge的edgecore的南向边缘侧,主要对接入kubeedge的终端设备,进行协议的适配和转换,使其可以和边缘设备通信,转换后的协议是我们前面描述的mqtt协议,当然…

快速上手配置firewalld

firewalld使用firewall-cmd命令配置策略。 查看当前firewalld当前服务运行状态 firewall-cmd --state firewalld防火墙状态还用使用如下命令查看状态 systemctl status firewalld 查看所有打开运行的端口 firewall-cmd --zonepublic --list-ports 查看区域信息情况 firewall…

04 Android基础--RelativeLayout

04 Android基础--RelativeLayout什么是RelativeLayout?RelativeLayout的常见用法:什么是RelativeLayout? 相对布局(RelativeLayout)是一种根据父容器和兄弟控件作为参照来确定控件位置的布局方式。 根据父容器定位 在相…

maven高级知识。

目录 一、分模块开发 1、分模块开发设计 2、依赖管理 二、继承和聚合 1、聚合 2、继承 三、属性 1、基本介绍 2、版本管理 四、多环境配置与应用 1、多环境开发 2、跳过测试 五、私服 1、私服安装 2、私服仓库分类 一、分模块开发 1、分模块开发设计 ▶ 示意图 …