JVM是如何创建一个对象的?

news2024/9/28 5:34:10

image-20240707151924408

哈喽,大家好🎉,我是世杰

本文我为大家介绍面试官经常考察的**「Java对象创建流程」**

照例在开头留一些面试考察内容~~

面试连环call

  1. Java对象创建的流程是什么样?
  2. JVM执行new关键字时都有哪些操作?
  3. JVM在频繁创建对象时,如何保证线程安全?
  4. Java对象的内存布局是什么样的?
  5. 对象头都存储哪些数据?

带着这些问题,让我们开始吧!🎉🎉🎉


1. 对象创建流程

当虚拟机遇到一个字节码 new 指令的时候,首先去检查这个指令的参数是否能够在常量池中定位到一个类的符号引用。并且检查这个符号引用代表的类是否被虚拟机类加载器加载。如果没有,必须先执行类加载的流程。(PS:类加载的过程可以看我之前的文章)

new指令对应到语言层面上讲是,new 关键词对象克隆对象序列化等。

类的生命周期

在类的检查通过过后

1、虚拟机就会为新生成对象分配内存。对象所需要的内存大小在类加载的时候决定。

2、内存分配完成后,虚拟机会将这块分配到的内存空间(不包括对象头)都初始化为零值

3、之后要进行对象进行初始化设置,比如元数据、对象的哈希编码、对象的 GC 分代年龄偏向锁状态等信息这些信息都用于存放到**对象头(Object Header)**中。

4、执行 new 指令之后会接着执行构造器方法,把对象按照程序员的意愿进行初始化(构造方法)

这样一个真正可用的对象才算完全产生出来。

image

『总结对象创建的过程』

  • 类加载检查
  • 分配内存
  • 初始化零值
  • 设置对象头
  • 执行init方法,进行初始化

2. 对象内存布局

在详细聊加载流程之前,先说说对象在JVM堆中的内存布局(这里讲的HotSpot虚拟机对象结构)

被JVM加载对象内部结构分为:对象头实例数据对齐填充

img

2.1 对象头

  • 对象标记(Mark Word),如哈希码(HashCode)、GC分代年龄锁状态标志线程持有的锁偏向线程ID偏向时间戳等。这部分我们称之为"Mard Word"。
  • 类元信息(Class Pointer),即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
  • 数组长度(Length),如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中无法确定数组的大小。

2.2 实例数据

  • 实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类中继承下来的,还是在子类中定义的,都需要记录下来。HotSpot虚拟机默认的分配策略为longs/doubles、ints、shorts/chars、bytes/booleans、oop,从分配策略中可以看出,相同宽度的字段总是分配到一起

  • 存放类的属性(Field)数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度

  • 这部分内存按4字节对齐

2.3 内存填充/对齐填充

  • 虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐。

3. 创建流程详解

创建对象在判断类加载之后,还会判断内存是否规整,根据判断结构选择使用空闲列表还是指针碰撞的内存分配方式,在分配内存时还会考虑线程并发处理,使用CAS或者是TLAB来处理,然后在执行初始化零值、设置对象头、执行<init>方法

img

3.1 分配内存

类加载检查通过后,那就要为实例化的对象分配内存。对象所需内存的大小在类加载完成后便完全确定(对象内存布局),为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。

『分配方式』

根据Java堆中是否规整有两种内存的分配方式:(Java堆是否规整由所采用的垃圾收集器是否带有压缩整理功能决定)

  • 指针碰撞(Bump the pointer)
    Java堆中的内存是规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,分配内存也就是把指针向空闲空间那边移动一段与内存大小相等的距离。
  • 空闲列表(Free List)
    Java堆中的内存不是规整的,已使用的内存和空闲的内存相互交错,虚拟机维护一张列表,记录哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。

b5654999074be8496a4208e703c259efc42ae8

『并发处理』

对象频繁分配的过程中,即使只修改一个指针所指向的位置,但是在并发的情况下也不是线程安全的,可能出现正在给 A 对象分配内存,指针还没有来得及修改,对象 B 又同时使用原来的指针进行内分配的情况。需要借助以下方式实现线程安全

  • CAS(compare and swap)对分配内存空间的动作进行同步处理,虚拟机采用CAS配上失败重试的方式保证更新操作的原子性。
  • 本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存。

3.2 初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这里的零值是指JAVA中字段默认的值

  • 如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。
  • 这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
  • 注意这一步赋值是对象实例字段零值,跟类加载过程中链接中的准备阶段做区分,准备是为类static变量赋零值

3.3 设置对象头

初始化零值之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头Object Header之中

对象内部结构

3.4 执行init方法

完成上述流程,其实已经完成了虚拟机中内存的创建,但是我们在 Java 执行 new 创建对象的角度才刚刚开始,我们还需要调用构造方法初始化对象(可能还需要在此前后调用父类的构造方法、初始化块等)。进行 Java 对象的初始化。


参考文章

十分钟搞懂Java引用、对象和内存

Java对象创建流程

JVM 从入门到放弃之 Java 对象创建过程

JAVA对象的创建及内存分配详解

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

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

相关文章

大连网站制作需要注意哪些问题

在制作大连网站时&#xff0c;需要注意以下几个问题&#xff1a; 1. 目标受众&#xff1a;首先要明确网站的目标受众是谁&#xff0c;根据受众的特点和需求来设计网站的内容和结构。比如&#xff0c;如果目标受众是年轻人&#xff0c;网站的设计风格可以更加时尚和前卫&#xf…

windwos下mysql的udf提权

MySql UDF提权介绍 UDF(User Defined Functions)即用户自定义函数&#xff0c;通过这种方式可以实现命令执行&#xff0c;其原理是通过lib_mysqludf_sys提供的函数可以执行系统命令 攻击场景:同之前利用日志写WebShell的场景&#xff0c;即堆叠注入或MySQL终端权限或类似phpMy…

使用Vue3、Pinia和Vite5打造高度还原的抖音仿制项目

douyin-vue 是一个模仿 抖音|TikTok 的移动端短视频项目。Vue 在移动端的"最佳实践"&#xff0c;媲美原生 App 丝滑流畅的使用体验。使用了最新的 Vue 技术栈&#xff0c;基于 Vue3、Vite5 、Pinia实现。数据保存在项目本地&#xff0c;通过 axios-mock-adapter 库拦…

【Hec-HMS】第一期:模型简介及软件安装

HEC-HMS模型简介及软件安装 HEC-HMS模型简介建模思路 HEC-HMS软件安装步骤1&#xff1a;安装InstallShield Wizard步骤2&#xff1a;安装HEC-HMS 参考 HEC-HMS模型简介 HEC-HMS(The Hydrologic Engineering Center’s-Hydrologic Modelimng System)&#xff0c;美国陆军工程兵…

邮件推送服务的自动化流程设置与优化技巧?

邮件推送服务如何定制化&#xff1f;邮件推送的安全性如何保障&#xff1f; 无论是大型企业还是小型企业&#xff0c;通过精准的邮件推送服务&#xff0c;可以实现客户关系管理的有效增强&#xff0c;提升品牌认知度和销售转化率。AokSend将探讨如何通过自动化流程设置与优化技…

路径规划 | 基于蚁群算法的三维无人机航迹规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 基于蚁群算法的三维无人机航迹规划&#xff08;Matlab&#xff09;。 蚁群算法&#xff08;Ant Colony Optimization&#xff0c;ACO&#xff09;是一种模拟蚂蚁觅食行为的启发式算法。该算法通过模拟蚂蚁在寻找食物时…

【MPPT太阳能升压控制器方案】远翔升压恒流驱动芯片FP7209单节电池升压24V,30V,36V,42V,48V全系列方案,高转换效率,输出带短路保护功能

高转换效率&#xff0c;太阳能控制器方案——详解太阳能控制器PWM / MPPT极简方案其设计要点&#xff0c;升压30V&#xff0c;36V&#xff0c;42V&#xff0c;48V 使用单颗芯片FP7209即实现两级升压到30V&#xff0c;36V&#xff0c;42V&#xff0c;48V&#xff0c;相对于单极升…

Milvus核心组件(1)

cluster 模式 上一篇其实已经说过 standalone 模式&#xff0c;其实集群模式大同小异&#xff0c;只是在不同机子间使用Kafka或者其他消息中间件保证数据及逻辑的一致性。 Log Broker&#xff0c;如Pulsar这样的系统&#xff0c;是专门设计来处理和管理日志数据的中间件。它主…

windows10开启防火墙,增加入站规则后不生效,还是不能访问后端程序

一、背景&#xff1a; 公司护网要求开启防火墙&#xff0c;开启防火墙后&#xff0c;前后端分离的项目调试受影响&#xff0c;于是增加入站规则开放固定的后台服务端口&#xff0c;增加的mysql端口3306和redis端口6379&#xff0c;别人都可以访问&#xff0c;但是程序的端口808…

AMEYA360:国民技术推出多款高能专用MCU产品

2024年7月8日&#xff0c;国民技术推出多款高能专用MCU产品。N32H482(通用控制)、N32H487(高性能互联)、N32GH473(电机控制)、N32H474(数字电源控制)四大系列高性能MCU新品&#xff0c;以及基于Arm Cortex M0内核实现的N32G052系列高性价比通用MCU新品。 全新一代高性能MCU新品…

JavaSE 面向对象程序设计进阶 IO流 字符输入输出流及底层原理

目录 字符输入流FileReader 空参的read方法 带参的read方法 字符输出流FileWriter 字符输入流底层原理 字符输出流底层原理 字符输入流FileReader 输入流 一次读一个字节 遇到中文时 一次读多个字节 输出流 底层会把数据按照指定的编码方式进行编码 在变成直接写到文件当…

企业化运维(7)_Zabbix企业级监控平台

官网&#xff1a;Zabbix :: The Enterprise-Class Open Source Network Monitoring Solution ###1.Zabbix部署### &#xff08;1&#xff09;zabbix安装 安装源 修改安装路径为清华镜像 [rootserver1 zabbix]# cd /etc/yum.repos.d/ [rootserver1 yum.repos.d]# vim zabbix.r…

SAP与易链SRM系统集成案例

一、项目环境 重庆润通控股&#xff08;集团&#xff09;有限公司成立于2007年&#xff0c;是一家集合汽柴油动力及终端、摩托车、储能电源、汽车零部件、金融服务等产业的多元化集团公司。现拥有员工超4000人&#xff0c;业务遍布全球80多个国家及地区&#xff0c;2021年营…

CDGA|数据治理:如何建立健全数据伦理和隐私保护机制?

随着数字化时代的到来&#xff0c;数据已成为推动社会进步和企业发展的重要资源。然而&#xff0c;随之而来的数据伦理和隐私保护问题也日益凸显。建立健全的数据治理体系&#xff0c;特别是强化数据伦理和隐私保护机制&#xff0c;已成为当务之急。 数据治理的重要性 数据治理…

GeoServer property 表达式注入代码执行漏洞(CVE-2024-36401)

GeoServer property 表达式注入代码执行漏洞(CVE-2024-36401) 1.漏洞描述 GeoServer 是一个开源的服务器软件&#xff0c;使用 Java 编写&#xff0c;主要功能是允许用户共享和编辑地理空间数据。它在设计时就考虑到了互操作性&#xff0c;支持使用开放标准来发布多种主流格式…

从新手到高手:Scala函数式编程完全指南,Scala IF…ELSE 语句(8)

1、Scala IF…ELSE 语句 Scala IF…ELSE 语句是通过一条或多条语句的执行结果&#xff08;True或者False&#xff09;来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: 1.1、if 语句 if 语句有布尔表达式及之后的语句块组成。 语法 if 语句的语法格式如下&…

After Detailer让图像自动修复

After Detailer&#xff08;简称adetailer&#xff09;是一个Stable Diffusion的自动Web-UI扩展&#xff0c;它能够自动化修复图像中的不完整部分&#xff0c;例如模糊的人脸等常见问题。在这篇文章中&#xff0c;你将了解它的工作原理、如何使用它&#xff0c;以及一些常见的使…

@RequestPart 与 @RequestBody、@RequestParam 注解的异同点

前言 RequestPart 注解是我们在JavaEE 开发中&#xff0c;比较常见的一个注解。它经常会与 RequestBody 、RequestParam 注解进行比较&#xff0c;这篇博文我们以案例和源码相结合&#xff0c;分析这几个注解的异同点。 案例演示 创建实体类 User Data NoArgsConstructor A…

图片海报怎么做成二维码展示?二维码分享图片的制作技巧

怎么把图片的宣传海报做成二维码呢&#xff1f;在做活动或者产品宣传时&#xff0c;都会制作精美的图片海报&#xff0c;除了打印传单或者制作展板的方式来展示外&#xff0c;将海报图片生成二维码&#xff0c;通过分享二维码来实现图片海报的快速传播&#xff0c;能够有效提升…

[数据结构] 基于插入的排序 插入排序希尔排序

标题&#xff1a;[数据结构] 排序#插入排序&希尔排序 水墨不写bug 目录 &#xff08;一&#xff09;插入排序 实现思路&#xff1a; 插入排序实现&#xff1a; &#xff08;二&#xff09;希尔排序 希尔排序的基本思想&#xff1a; 希尔排序的实现&#xff1a; 正…