当前位置: 首页 > news >正文

【JVM】详细解析java创建对象的具体流程

目录

一、java创建对象的几种方式

1.1、使用new关键字

 1.2、反射创建对象

1.2.1、Class.newInstance创建对象

1.2.2、调用构造器再去创建对象Constructor.newInstance

 1.3、clone实现

1.4、反序列化

二、创建对象的过程

2.1、分配空间的方式

1、指针碰撞

2、空闲列表

3、怎么选择分配方式

三、注意事项


一、java创建对象的几种方式

1.1、使用new关键字

调用类的构造方法创建对象

 1.2、反射创建对象

1.2.1、Class.newInstance创建对象

1.2.2、调用构造器再去创建对象Constructor.newInstance

先通过反射获取类中无参构造器,然后通过newInstance()获取对象

 1.3、clone实现

通过Clone创建对象,首先实体类中必须先实现Cloneable接口并复写Object的clone方法(因为Object的这个方法是protected的)

 

1.4、反序列化

序列化:指把 Java 对象转换为字节序列的过程;
反序列化:指把字节序列恢复为 Java 对象的过程;
此方式需要类先实现Serializable接口

public class TestStack {public static void main(String[] args) throws Exception {File file =new File("M:/Serializable.txt");FileOutputStream fileOutputStream = new FileOutputStream(file);ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);UserParam userParam =new UserParam("hello");outputStream.writeObject(userParam);FileInputStream fileInputStream  = new FileInputStream(file);ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);UserParam userParam1 = (UserParam)objectInputStream.readObject();userParam1.setNickName("world");System.out.println(userParam1);}
}

二、创建对象的过程

当Java虚拟机遇到一条字节码new指令时:

1、检查类是否已经被加载

        去常量池中查找该引用所指向的类有没有被虚拟机加载,如果没有被加载,那么会进行类的加载过程。类的加载过程需要经历:加载、链接、初始化三个阶段。对象的大小,在类加载完成时确定。(jdk1.8中,运行时常量池、类常量池存在于方法区中。)

2、 为对象分配内存空间

        JVM为对象分配空间,即把一块确定大小的内存块从Java堆中划分出来。

2.1、分配空间的方式

1、指针碰撞

        假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离。

①正常情况

②给对象分配内存后

 

这种方式的优点是工作简单,效率高,只需要移动指针就可以分配内存空间。

缺点也很明显:由于用指针碰撞分配内存空间分为两步:

1、读取指针当前的位置。

2、根据自身大小移动指针,不是原子操作,对象创建在虚拟机中是非常频繁的操作,在并发情况下,会导致执行读操作或执行写操作的结果与预设的结果不一致(指针划分不一致)。

        例如:线程A要给对象分配8kb,读取到指针当前的位置,时间片用完,切换到线程B,线程B要给它的对象分配16kb,也读取到指针当前的位置(和线程A读取到的一样),将指针向空闲内存方向移动16kb大小,线程B时间片用完,切换到线程A继续执行,由于线程A使用的指针位置还是之前读到的。(线程不安全问题)

③针对指针碰撞线程不安全,有两种方案:

1、同步处理(加锁)分配内存空间行为

采用 CAS 分配重试的方式来保证更新操作的原子性

2、把内存分配行为按照线程,划分在不同的内存空间进行

1、即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓存区时才需要同步锁定
2、虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。

2、空闲列表

        如果Java堆中的内存并不是规整的, 已被使用的内存和空闲的内存相互交错在一起,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。

3、怎么选择分配方式

        两种方式的选择由 Java 堆是否规整决定,Java 堆是否规整是由选择的垃圾收集器是否具有压缩整理能力决定的。

①将内存空间初始化为零值
        内存分配完成之后,虚拟机必须将分配到的内存空间(但不包括对象头)都初始化为零值。零值初始化意思就是对对象的字段赋0值,或者null值,这也就解释了为什么这些字段在不需要进程初始化时候就能直接使用。
        如果使用了TLAB的话,这一项工作也可以提前至TLAB分配时顺便进行。

②对对象进行必要的设置
        例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头中。

        从虚拟机的视角来看,一个新的对象已经产生了。但是从Java程序的视角看来,对象创建才刚刚开始——构造函数,即Class文件中的()方法还没有执行,所有的字段都为默认的零值,对象需要的其他资源和状态信息也还没有按照预定的意图构造好。

③执行实例的初始化方法init

        init方法包含成员变量、构造代码块的初始化,按照声明的顺序执行,执行对象的构造
方法,并把堆内对象的首地址赋值给引用变量。至此,对象创建成功。

三、注意事项

        并发情况下,需要考虑操作的步骤是不是原子性,如果不是,就要加锁。原子性就是动作不能再继续被拆分了,读是原子性,写也是原子性,但是读加上写就不是原子性。

相关文章:

【JVM】详细解析java创建对象的具体流程

目录 一、java创建对象的几种方式 1.1、使用new关键字 1.2、反射创建对象 1.2.1、Class.newInstance创建对象 1.2.2、调用构造器再去创建对象Constructor.newInstance 1.3、clone实现 1.4、反序列化 二、创建对象的过程 2.1、分配空间的方式 1、指针碰撞 2、空闲列表 …...

kafka怎么用代码读取数据

Kafka可以通过Java语言中的Kafka客户端库来读取数据。以下是一个简单的Java代码示例,通过Kafka Consumer API从Kafka集群中读取数据: java import java.util.Properties; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.…...

网关与路由器的区别

仅需2分钟,彻底明白网关的工作原理_哔哩哔哩_bilibili网关_百度百科 一、网关的概念 网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域…...

助力工业物联网,工业大数据之工单事实指标需求分析【二十】

文章目录 1:工单事实指标需求分析2:工单事实指标构建 1:工单事实指标需求分析 目标:掌握DWB层工单事实指标表的需求分析 路径 step1:目标需求step2:数据来源 实施 目标需求:基于工单信息统计等…...

python_PyQt5开发工具结构基础

写在前面: 考虑已经陆陆续续在平台写了几篇PyQt5开发的小工具,后续还会继续发布新的新工具,这些工具都基于一个基础结构往上构建,这个基础结构是本人自己开发的习惯,在这里把工具的基础结构代码抽取出来,后…...

【C++】入门基础2

引用 概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间 类型& 引用变量名(对象名) 引用实体; 注意:引用类型必须和引用实体是…...

Reinforcement Learning with Code 【Chapter 8. Value Funtion Approximation】

Reinforcement Learning with Code This note records how the author begin to learn RL. Both theoretical understanding and code practice are presented. Many material are referenced such as ZhaoShiyu’s Mathematical Foundation of Reinforcement Learning, . 文章…...

常用InnoDB参数介绍

常用InnoDB参数介绍 1 状态参数1.1 InnoDB 缓冲池状态监控1.1.1 Innodb_buffer_pool_pages_total1.1.2 Innodb_buffer_pool_pages_data1.1.3 Innodb_buffer_pool_bytes_data1.1.4 Innodb_buffer_pool_pages_dirty1.1.5 Innodb_buffer_pool_bytes_dirty1.1.6 Innodb_buffer_pool…...

云原生网关部署新范式丨 Higress 发布 1.1 版本,支持脱离 K8s 部署

作者:澄潭 版本特性 Higress 1.1.0 版本已经 Release,K8s 环境下可以使用以下命令将 Higress 升级到最新版本: kubectl apply -f https://github.com/alibaba/higress/releases/download/v1.1.0/customresourcedefinitions.gen.yaml helm …...

【通讯录】--C语言

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...

通过两种实现方式理解CANoe TC8 demo是如何判断接收的以太网报文里的字段的

假设有一个测试用例,需求是:编写一个测试用例,发送一条icmpv4 echo request报文给DUT,identifier字段设置为10。判断DUT能够回复icmpv4 echo reply报文,且identifier字段值为10。 实现:在canoe的simulation setup界面插入一个test节点,ip地址为:192.168.0.1,mac地址为…...

Mysql- 存储引擎

目录 1.Mysql体系结构 2.存储引擎简介 3.存储引擎特点 InnoDB MyISAM Memory 4.存储引擎选择 1.Mysql体系结构 MySQL整体的逻辑结构可以分为4层: 连接层:进行相关的连接处理、权限控制、安全处理等操作 服务层:服务层负责与客户层进行…...

vite / nuxt3 项目使用define配置/自定义,可以使用process.env.xxx获取的环境变量

每日鸡汤:每个你想要学习的瞬间,都是未来的你向自己求救 首先可以看一下我的这篇文章了解一下关于 process.env 的环境变量。 对于vite项目,在我们初始化项目之后,在浏览器中打印 process.env,只有 NODE_ENV这个变量&…...

在Linux、Ubuntu中跨平台编译ARM(AARCH64)平台的binutils

Binutils 是GNU(https://www.gnu.org/)提供的一组二进制工具的集合。通常,在已经安装了Linux操作系统的个人电脑上,系统就已经自带了这个工具集。但在进行嵌入式开发的时候,可能会用到支持ARM64平台的Binutils,这时就需要用到交叉编译。 此前,在【1】我们已经介绍过Ubun…...

SpringCloudAlibaba微服务实战系列(五)Sentinel1.8.5+Nacos持久化

Sentinel数据持久化 前面介绍Sentinel的流控、熔断降级等功能,同时Sentinel应用也在面临着一个问题:我们在Sentinel后台管理界面中配置了一堆流控、降级规则,但是Sentinel一重启,这些规则全部消失了。那么我们就要考虑Sentinel的持…...

pytest中conftest的用法以及钩子基本使用

一、conftest是什么? conftest是pytest进阶中的高级应用,最近正好用到这一块儿,研究之后,向大家分享该高级应用。 二、使用步骤 1.conftest代码块 以全局性使用driver为主,只启动一次浏览器: pytest.fi…...

数据结构---顺序栈、链栈

特点 typedef struct Stack { int* base; //栈底 int* top;//栈顶 int stacksize //栈的容量; }SqStack; typedef struct StackNode { int data;//数据域 struct StackNode* next; //指针域 }StackNode,*LinkStack; 顺序栈 #define MaxSize 100 typedef struct Stack { int*…...

我的MacBook Pro:维护心得与实用技巧

文章目录 我的MacBook Pro:维护心得与实用技巧工作电脑概况:MacBook Pro 2019款 16 寸日常维护措施个人维护技巧其他建议 我的MacBook Pro:维护心得与实用技巧 无论是学习还是工作,电脑都是IT人必不可少的重要武器。一台好电脑除…...

Higress非K8S安装

Higress非K8S安装 文章目录 Higress非K8S安装环境安装安装higress进入到higress 的目录下修改下nacos的地址启动Higress登录higress管理页面 Higress 是基于阿里内部构建的下一代云原生网关,官网介绍:https://higress.io/zh-cn/docs/overview/what-is-hi…...

QT--day4(定时器事件、鼠标事件、键盘事件、绘制事件、实现画板、QT实现TCP服务器)

QT实现tcpf服务器代码:(源文件) #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间server new QTc…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

【生成模型】视频生成论文调研

工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

Kafka入门-生产者

生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...