【JVM】Java类的加载机制!

news2024/9/25 19:25:21

一、类的生命周期

类加载过程包含:加载验证准备解析初始化 ,一共包括5 个阶段。

(1)加载:

简单来说就是将java类的字节码文件加载到机器内存中。在加载类时,Java虚拟机必须完成以下3件事情: 

  • 通过类的完全限定名称获取定义该类的二进制字节流。
  • 将该字节流表示的静态存储结构转换为Metaspace元空间区的运行时存储结构。
  • 在内存中生成一个代表该类的 Class 对象,作为元空间区中该类各种数据的访问入口。

(2)验证:

确保 Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

(3)准备:

为类的静态分配内存,并将其初始化为默认值当一个类验证通过时,虚拟机就会进入准备阶段。在这个阶段,虚拟机就会为这个类分配相应的内存空间,并设置默认初始值。Java虚拟机为各类型变量默认的初始值如表所示。

类型

默认初始值

byte

0

short

0

int

0

long

0L

float

0.0f

double

0.0

char

\u0000

boolean

false

reference

null

没有对static fianl修饰的变量进行赋值,因为final修饰的变量已经在编译阶段就进行了赋默认值,而在准备阶段进行的是显式赋值 

(4)解析:

将常量池的符号引用替换为直接引用的过程。其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。

符号引用就是一些自变量的引用,和虚拟机的内部数据结构和和内存布局无关。比较容易理解的就是在Class类文件中,通过常量池进行了大量的符号引用。但是在程序实际运行时,只有符号引用是不够的,比如当如下println()方法被调用时,系统需要明确知道该方法的位置。

(5)初始化:

初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>()方法的过程

对于<clinit>()方法的调用,也就是类的初始化,虚拟机会在内部确保其多线程环境中的安全性。

虚拟机会保证一个类的()方法在多线程环境中被正确地加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的<clinit>()方法,其他线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕。

正是因为函数<clinit>()带,因此,如果在一个类的<clinit>()方法中有耗时很长的操作,就可能造成多个线程阻塞,引发死锁。并且这种死锁是很难发现的,因为看起来它们并没有可用的锁信息。

如果之前的线程成功加载了类,则等在队列中的线程就没有机会再执行<clinit>()方法了。那么,当需要使用这个类时,虚拟机会直接返回给它已经准备好的信息。

二、类加载的主动引用和被动引用 

(1)主动引用(会发生初始化)

  1.  遇到new、getstatic、putstatic、invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
  2. 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
  3. 加载一个类,如果其父类还未加载,则先触发该父类的加载。
  4. 当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main() 方法的类),虚拟机会先加载这个类。
  5. 当一个接口中定义了 JDK8 新加入的默认方法(被 default 关键字修饰的接口方法)时,如果有这个接口的实现类发生了加载,则该接口要在实现类之前被加载。

(2)被动引用(看上去会,其实不会发生初始化):

  1. 通过子类引用父类的静态字段,不会导致子类初始化
  2. 通过数组定义类引用类,不会触发此类的初始化
  3. 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化

三、类加载器

类加载器是Java虚拟机中的一个子系统,用于将类的字节码文件加载到内存中,并转换为Java的类对象。Java虚拟机需要根据类的全名来定位并加载类的字节码文件,而类加载器负责从文件系统、网络等位置查找类文件,并加载到Java虚拟机中。

Java虚拟机中有三种类加载器,分别是启动类加载器、扩展类加载器和应用程序类加载器。

(1)Bootstrap ClassLoader:启动加载器

它负责加载Java的核心类(如String、System等)。它比较特殊,因为它是由原生C++代码实现的,并不是java.lang.ClassLoader的子类。启动类加载器无法被 Java 程序直接引用,所以下面的运行结果为null:

(2)Extension ClassLoader:扩展类加载器

它负责加载JRE的扩展目录(%JAVA_HOME%/jre/lib/ext)中JAR包的类,我们可以通过把自己开发的类打包成JAR文件放入扩展目录来为Java扩展核心类以外的新功能。

(3)System ClassLoader(或Application ClassLoader):应用程序(系统)类加载器

它负责在JVM启动时加载来自Java命令的-classpath选项、java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader来获取系统类加载器:

四. 对象的创建过程

Step1:类加载检查

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

Step2:分配内存

类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。内存分配的查找方式“指针碰撞”“空闲列表” 两种。

Step3:初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

Step4:设置对象头

初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

Step5:执行 init 构造方法

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从Java 程序的视角来看,对象创建才刚开始,<init> 构造方法还没有执行,目前所有的字段都还为零。所以一般来说,执行 new 指令之后会接着执行 <init> 构造方法,把对象按照程序逻辑的意愿进行初始化,这样一个真正可用的对象才算完整创建出来。

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

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

相关文章

Matlab图像处理-HSI模型

HSI模型 HSI模型是从人的视觉系统出发&#xff0c;直接使用颜色三要素色调(Hue)、饱和度(Saturation)和亮度&#xff08;Intensity&#xff09;来描述颜色。 亮度是指人眼感知光线的明暗程度。光的能量越大&#xff0c;亮度就越大。 色调是颜色最重要的属性。 它决定了颜色的…

深入了解Vue.js框架:构建现代化的用户界面

目录 一.Vue前言介绍 二.Vue.js框架的核心功能与特性 三.MVVM的介绍 四.Vue的生命周期 五.库与框架的区别 1.库&#xff08;Library&#xff09;&#xff1a; 2.框架&#xff08;Framework&#xff09;&#xff1a; 六.Vue常用指令演示 1.v-model 2.v-on:click&…

Python爬虫自动切换爬虫ip的完美方案

在进行网络爬虫时&#xff0c;经常会遇到需要切换爬虫ip的情况&#xff0c;以绕过限制或保护自己的爬虫请求。今天&#xff0c;我将为你介绍Python爬虫中自动切换爬虫ip的终极方案&#xff0c;让你的爬虫更加高效稳定。 步骤一&#xff1a;准备爬虫ip池 首先&#xff0c;你需要…

python调用函数详解

一、定义函数与调用函数的顺序 函数被定义后&#xff0c;本身是不会自动执行的&#xff0c;只有在被调用后&#xff0c;函数才会被执行&#xff0c;得到相应的结果。但是在 Python 中我们要注意一个关键点&#xff0c;就是Python不允许前向引用&#xff0c;即在函数定义之前&a…

LeetCode 面试题 04.09. 二叉搜索树序列

文章目录 一、题目二、C# 题解 一、题目 从左向右遍历一个数组&#xff0c;通过不断将其中的元素插入树中可以逐步地生成一棵二叉搜索树。 给定一个由不同节点组成的二叉搜索树 root&#xff0c;输出所有可能生成此树的数组。 点击此处跳转题目。 示例 1: 输入: root [2,1,3]…

商家收款码手续费收费标准

不管是微信还是支付宝&#xff0c;商户最低的收款手续费率可以达到0.2%费率。一般我们普通商户的收款费率一般在0.6左右&#xff0c;当然也有使用0.3的&#xff0c;也就是1万元的费率是30-60块钱&#xff0c;对于一些流水比较大的商家来说&#xff0c;确实很有必要把这个手续费…

为什么有了IP地址还需要MAC地址?

上午好&#xff0c;我的网工朋友。 今天想和你聊聊Mac地址。 到底啥是Mac地址&#xff1f;官方直译是媒体存取控制位址&#xff0c;是一个用来确认网络设备位置的位址。 在OSI模型中&#xff0c;第三层网络层负责IP地址&#xff0c;第二层数据链路层则负责MAC位址。 MAC地址…

【JavaEE】多线程(三)

多线程&#xff08;三&#xff09; 续上文&#xff0c;多线程&#xff08;二&#xff09;&#xff0c;我们已经讲了 创建线程Thread的一些重要的属性和方法 那么接下来&#xff0c;我们继续来体会了解多线程吧~ 文章目录 多线程&#xff08;三&#xff09;线程启动 startsta…

微信小程序如何跳转到tabBar页面、如何携带参数过去

文章目录 一、跳转链接时&#xff0c;不能使用navigator标签、 wx.navigateTo、wx.redirectTo方法跳转页面问题解决&#xff1a;1、wx.switchTab(Object object)2、wx.reLaunch(Object object) 二、不能用常规的方式给tabBar的页面传递参数问题解决&#xff1a;1、用前面提到的…

聚观早报 | 联发科天玑9300跑分曝光;OPPO A2 Pro开启预售

【聚观365】9月18日消息 联发科天玑9300跑分曝光 OPPO A2 Pro开启预售 哪吒汽车泰国累计交付破1万台 小米13T系列最新渲染图出炉 酷派手机新品通过工信部入网 联发科天玑9300跑分曝光 今年上半年&#xff0c;联发科推出了天玑9200移动平台&#xff0c;截至目前已有多款机…

二蛋赠书三期:《C#入门经典(第9版)》

文章目录 前言活动规则参与方式本期赠送书籍介绍作者介绍内容简介读者对象获奖名单 结语 前言 大家好&#xff01;我是二蛋&#xff0c;一个热爱技术、乐于分享的工程师。在过去的几年里&#xff0c;我一直通过各种渠道与大家分享技术知识和经验。我深知&#xff0c;每一位技术…

Apache httpd 安全漏洞处理-升级httpd版本

文章目录 前言一、现状二、使用codeit库升级Apache1. 安装epel-release2. 下载codeit的repo文件3. 查看版本信息4. 更新httpd版本后确认版本5. 重启httpd服务 总结 前言 手上有台zabbix-server服务器&#xff0c;用了httpd的服务支撑&#xff0c;漏扫时发现有很多的Apache htt…

具体项目下解决Echarts多端同步开发和维护的问题

具体问题场景 PC端和移动端需要同时上线图表功能&#xff08;没有多余工时&#xff09; 之后的版本迭代&#xff08;功能、样式、配置等&#xff09;默认双端同步&#xff0c;开发人员只希望维护一套代码 Echarts在移动端有部分功能不兼容不支持 Echarts在移动端的坑 ① 移动端…

AI与医疗保健:革命性技术如何拯救生命

文章目录 引言AI的应用领域1. 影像识别2. 疾病诊断3. 药物研发4. 个性化治疗 AI技术1. 机器学习2. 深度学习3. 自然语言处理4. 基因组学 实际案例1. Google Health的深度学习模型2. IBM Watson for Oncology3. PathAI的病理学分析 道德和隐私考虑结论 &#x1f389;欢迎来到AIG…

振弦采集仪和传感器在岩土工程中安装方法的关键要点

振弦采集仪和传感器在岩土工程中安装方法的关键要点 振弦采集仪和传感器在岩土工程中的安装方法是岩土工程中非常关键的过程。其安装质量的好坏直接影响实验数据的准确性&#xff0c;进而影响工程设计和施工效果。因此&#xff0c;在实际工作中&#xff0c;如何正确的安装振弦…

0基础学习VR全景平台篇 第100篇:美团酒店丨平台上传全景全流程

目前美团平台已经具备VR全景图在美团App客户端的展示能力&#xff0c;但目前E-Booking暂未开通上传通道&#xff0c;若商家您有全景图且有意愿上传至平台&#xff0c;需要签署授权书&#xff0c;并依照规定的格式要求发送邮件申请&#xff0c;由平台代为人工上传。具体规则和要…

一款非常容易上手的报表工具,简单操作实现BI炫酷界面数据展示,驱动支持众多不同类型的数据库,可视化神器,免开源了

一款非常容易上手的报表工具&#xff0c;简单操作实现BI炫酷界面数据展示&#xff0c;驱动支持众多不同类型的数据库&#xff0c;可视化神器&#xff0c;免开源了。 在互联网数据大爆炸的这几年&#xff0c;各类数据处理、数据可视化的需求使得 GitHub 上诞生了一大批高质量的…

循环神经网络——上篇【深度学习】【PyTorch】【d2l】

文章目录 6、循环神经网络6.1、序列模型6.1.1、序列模型6.1.2、条件概率建模6.1.2、代码实现 6.2、文本预处理6.2.1、理论部分6.2.2、代码实现 6.3、语言模型和数据集 6、循环神经网络 6.1、序列模型 6.1.1、序列模型 序列模型主要用于处理具有时序结构的数据&#xff0c; *…

OA 电子审批流程是什么?

公司中&#xff0c;最最最常见也是最最最多的就是——各种审批。 我当年第一次实习&#xff0c;在一家国企的行政部门&#xff0c;我们部门领导那个时候最主要的工作就是“打通流程”&#xff0c;咱也不知道他在打通什么流程&#xff0c;反正这个很重要就是了。 结果&#xf…

docker swarm集群

集群构建 不包含在任何 Swarm 中的 Docker 节点&#xff0c;称为运行于单引擎&#xff08;Single-Engine&#xff09;模式。一旦被加入 Swarm 集群&#xff0c;则切换为 Swarm 模式。第一步我们要做的就是初始化 Swarm。 初始化swarm集群 将本机作为manager节点 docker swar…