JVM-【面试题】-带你了解对象的创建过程

news2025/1/16 3:59:30

本文介绍对象在jvm的创建过程

该图是对象在jvm的创建过程

一、类加载检查

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

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

二、分配内存

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类 加载完成后便可完全确定,为对象分配空间的任务等同于把 一块确定大小的内存从Java堆中划分出来。

这个步骤有两个问题:

1.如何划分内存。

2.在并发情况下, 可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。

2.1 划分内存的方法

  • “指针碰撞”(Bump the Pointer)(默认用指针碰撞)

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

  • “空闲列表”(Free List)

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

2.2 解决并发问题的方法:

  • CAS(compare and swap)

虚拟机采用CAS配上失败重试的方式保证更新操作的原子性来对分配内存空间的动作进行同步处理。

  • 本地线程分配缓冲(Thread Local Allocation Buffer、TLAB)

把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存。通过-XX:+/-UseTLAB参数来设定虚拟机是否使用TLAB(JVM会默认开启-XX:+UseTLAB),-XX:TLABSize 指定TLAB大小。

由于TLAB空间一般不会很大,因此大对象无法在TLAB上进行分配,总是会直接分配在堆上。TLAB空间由于比较小,因此很容易装满。比如,一个100K的空间,已经使用了80KB,当需要再分配一个30KB的对象时,肯定就无能为力了。这时虚拟机会有两种选择,第一,废弃当前TLAB,这样就会浪费20KB空间;第二,将这30KB的对象直接分配在堆上,保留当前的TLAB,这样可以希望将来有小于20KB的对象分配请求可以直接使用这块空间。实际上虚拟机内部会维护一个叫作refill_waste的值,当请求对象大于refill_waste时,会选择在堆中分配,若小于该值,则会废弃当前TLAB,新建TLAB来分配对象。这个阈值可以使用TLABRefillWasteFraction来调整,它表示TLAB中允许产生这种浪费的比例。默认值为64,即表示使用约为1/64的TLAB空间作为refill_waste。默认情况下,TLAB和refill_waste都会在运行时不断调整的,使系统的运行状态达到最优

三、初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头)。

如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

这时候进行内存分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在堆中。其次,这里所说的初始值“通常情况”下是数据类型的零值,假设一个类变量的定义为:

public static int value = 123;

那么,变量value在这阶段过后的值为0而不是123。因为这时候尚未开始执行任何java方法,而把value赋值为123的putstatic指令是程序被编译后,存放于类构造器方法<clinit>()之中,所以把value赋值为123的动作将在初始化阶段才会执行。至于“特殊情况”是指:当类字段的字段属性是ConstantValue时,会在准备阶段初始化为指定的值,所以标注为final之后,value的值在这阶段初始化为123而非0

public static final int value = 123;

四、设置对象头

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

在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、 实例数据(Instance Data)和对齐填充(Padding)。 HotSpot虚拟机的对象头包括两部分信息,第一部分用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时 间戳等。对象头的另外一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

32位对象头

64位对象头

五、执行init方法

执行方法,即对象按照程序员的意愿进行初始化。对应到语言层面上讲,就是为属性赋值(注意,这与上面的赋零值不同,这是由程序员赋的值),和执行构造方法。

类初始化阶段是类加载过程的最后一步。在前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的java程序代码(字节码)

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

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

相关文章

图机器学习-图机器学习传统方法

图机器学习-图机器学习传统方法 最近在学习一些GNN相关的知识&#xff0c;想写一些笔记记录一下自己的学习过程&#xff0c;主要的学习资料为CS224W课程主页上面的资料和b站同济子豪兄的中文讲解。这篇博客是我2023年的第一篇博客&#xff0c;想以图机器学习中的传统方法作为博…

项目管理工具dhtmlxGantt甘特图入门教程(八):数据加载(三)

dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足项目管理控件应用程序的所有需求&#xff0c;是最完善的甘特图图表库。 这篇文章给大家讲解如何利用 dhtmlxGantt正确保存和显示任务的结束日期&#xff0c;本节将给你一个明确答案。 Dht…

异常-捕获业务异常踩坑记录

事情是这样&#xff0c;用了google的一个本地缓存框架&#xff0c;就是在查询数据的时候如果有就取缓存&#xff0c;没有就发http请求调接口&#xff0c;但是http请求也会有查询失败的时候&#xff0c;查询失败就会手动抛一个业务异常&#xff0c;然后我会在外层各种捕获异常&a…

三消游戏查找算法的原理和实现

本文首发于公众号&#xff1a; 小蚂蚁教你做游戏。欢迎关注领取更多学习做游戏的原创教程资料&#xff0c;每天学点儿游戏开发知识。嗨&#xff01;大家好&#xff0c;我是小蚂蚁。今天这篇文章分享一下三消查找算法的原理和实现&#xff0c;其实三消的机制最早源于《宝石方块》…

无联不成春,2023创宇网安春联展!

春 联 又叫“春贴”“门对”“对联” 它以对仗工整、简洁精巧的文字 描绘美好形象&#xff0c;寄托美好愿望 是中国独特的文学形式 网络安全的列车已驶入2023&#xff0c;癸卯兔年新春将至&#xff01; 热爱中华优秀传统文化的创宇人&#xff0c;也纷纷以春联为载体&…

大网进阶安全刷题讲解(带答案)(1)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.大网进阶安全刷题 前言 本章将会讲解大网进阶安全刷题讲解。 一.大网进阶…

测试开发 | AppCrawler 自动遍历测试实践(二):定制化配置

本文为霍格沃兹测试学院学院学员课程 AppCrawler 学习笔记&#xff0c;文末加群一起学习交流。 定制化配置 自动遍历测试技术以及工具该如何选择和快速入门&#xff1f;经过对比和需求&#xff0c;最终选择测试架构师思寒大佬的 AppCrawler 作为自动遍历测试的工具。以下就分享…

LeetCode 112. 路径总和

&#x1f308;&#x1f308;&#x1f604;&#x1f604; 欢迎来到茶色岛独家岛屿&#xff0c;本期将为大家揭晓LeetCode 112. 路径总和&#xff0c;做好准备了么&#xff0c;那么开始吧。 &#x1f332;&#x1f332;&#x1f434;&#x1f434; 一、题目名称 LeetCode 112…

Cadence PCB仿真使用Allegro PCB SI按照指定的规则自动创建差分对方法图文教程

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 目录 1,概述2,配置方法3,总结1,概述 本文简单介绍使用Allegro PCB SI按照指定的规则自动创建差分的方法。 2,配置方法 第1步:打开待仿真的PCB文件,并确认软件为Allegro PCB SI 如果,打开软件不是Allegro PCB SI则可…

在使用示波器时,为什么有些波形感觉一直在晃?

我们可以从三个角度进行分析&#xff1a; 采样分析&#xff1a; 1、示波器采样信号的过程如上图&#xff1a;采样——处理——采样——处理。 2、处理时间也称死区时间&#xff0c;死区时间内示波器不监测输入信号。 3、提高波形刷新率&#xff0c;实质上是减少了死区时间&…

MyBatis-Plus数据安全保护(配置安全)

SpringBootMyBatis-Plus配置安全 1.该功能为了保护数据库配置及数据安全&#xff0c;在一定的程度上控制开发人员流动导致敏感信息泄露2.加密配置 mpw: 开头紧接加密内容&#xff08; 非数据库配置专用 YML 中其它配置也是可以使用的 &#xff09;3.随机密钥请负责人妥善保管&a…

设计模式_创建型模式 -《原型模式》

设计模式_创建型模式 -《原型模式》 笔记整理自 黑马程序员Java设计模式详解&#xff0c; 23种Java设计模式&#xff08;图解框架源码分析实战&#xff09; 概述 原型模式 (Prototype Pattern) &#xff1a;用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建…

Kafka的相关知识

一. Kafka基本介绍 Kafka是一个分布式、支持分区的&#xff08;partition&#xff09;、多副本的&#xff08;replica&#xff09;&#xff0c;基于zookeeper协调的分布式消息系统。具有&#xff1a;高吞吐量、低延迟、可扩展性、持久性、可靠性、容错性、高并发等特性。常见的…

RabbitMQ(五)常见面试题

目录1. 什么是 RabbitMQ&#xff1f;2.为什么要使用 RabbitMQ&#xff1f;3.使用 RabbitMQ 的场景4.如何确保消息正确地发送至 RabbitMQ&#xff1f;如何确保消息接收方消费了消息&#xff1f;5.如何避免消息重复投递或重复消费&#xff1f;6.消息基于什么传输&#xff1f;7.消…

基于java ssm springboot网上蛋糕商城项目设计和实现

基于java ssm springboot网上蛋糕商城项目设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源…

CAD中还能装ArcGIS?还能加载影像?定义坐标系?

时常我们需要CAD中插入影像 需要CAD数据转换GIS数据 需要CAD加载GIS数据 需要将CAD与GIS数据套库 却被坐标系搞蒙了 今天&#xff0c;我们就来解决以上的问题&#xff0c;介绍一款免费的ArcGIS插件——ArcGIS for AutoCAD。 这个模块插件可以直接访问在线地图。直接在CAD中…

Java实验——定义一个表示学生信息的类Student,要求如下:

一、题目要求 定义一个表示学生信息的类Student&#xff0c;要求如下&#xff1a; &#xff08;1&#xff09;类Student的成员变量&#xff1a; sNO 表示学号&#xff1b;sName表示姓名&#xff1b;sSex表示性别&#xff1b;sAge表示年龄&#xff1b;sJava&#xff1a;表示…

测试开发 | 如何模拟真实使用场景?mock 技术来帮你

mock 是一种通过代理修改请求与响应&#xff0c;从而辅助构造更多应用场景的工具。比如在工作中&#xff0c;可能需要 mock 第三方的回调给到测试人员测试的环境&#xff0c;从而更顺利的开展测试工作&#xff0c;也使得测试环境更接近真实的使用场景。Charles 修改请求与响应M…

Android自定义时间选择器

效果图 一、添加NumberPicker开源库 需要添加以下控件 仓库地址&#xff1a; https://github.com/ShawnLin013/NumberPicker implementation io.github.ShawnLin013:number-picker:2.4.13 二、 添加弹出框主题样式 在drawable文件夹下新建一个bg_bottom_dialog.xml&…

jenkins结合gitlable企业集成部署实战

简介 Jenkins是一个开源软件项目&#xff0c;起源于Hudson&#xff08;Hudson是商用的&#xff09;&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成 1.0 …