JVM:Java类加载机制

Java类加载机制的全过程:

        加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始, 这是为了支持Java语言的运行时绑定特性(也称为动态绑定或晚期绑定)。

1、加载(Loading)

        ”加载“是”类加载“的一个阶段,再这个阶段Java虚拟机需要完成三件事:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 再堆中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口。

就是将 java的字节码文件(.Class)文件加载到内存当中,然后在方法区当中根据这个文件构建这个类的类模型,这个类包含了从字节码文件中解析出来的常量池、类方法、等信息。然后再堆中生成这个java.lang.Class对象,用来封装方法区内的类模型的数据结构。反射就是通过这个Class对象提供的接口去访问方法区中的数据模型。(类加载器完成),Class 类的构造方法是私有的,只有 JVM 能够创建。

数组情况有些不同,数组类本身不是通过类加载器完成,而是由Java虚拟机直接再内存中动态构造出来。数组内的元素是通过类的加载器完成的。

2、连接(Linking)

  2.1 验证(Verification)

    验证是连接阶段的第一步,这一步骤是为了确保Class文件的字节流包含的信息符合规范,确保这些信息再运行后不会危害虚拟机自身安全。

2.1.1、文件格式验证

        这提阶段要验证的字节流是否符合Class文件格式规范,并且能被当前版本虚拟机处理,例如是否以魔数0xCAFEBABE开头,主、次版本号是否在当前Java虚拟机接受范围之内等等。只有经过哟了这部分的验证之后字节流才能进入到方法区当中去储存,后面三个验证阶段则是再方法区进行的。

2.1.2、元数据验证(元数据:描述数据的数据。

        这个部分是对字节码描述信息进行语义分析,如这个类是否有父类,这个类的父类是否有继承了不被允许的类、抽象方法是否有实现等等,看看有没有错误。

2.1.3、字节码验证

        字节码验证也是验证过程中最为复杂的一个过程。它试图通过对字节码流的分析,判断字节码是否可以被正确地执行。比如:在字节码的执行过程中,是否会跳转到一条不存在的指令。函数的调用是否传递了正确类型的参数。变量的赋值是不是给了正确的数据类型等。

      如果一个类型中有方法体的字节码没有通过字节码验证,那它肯定是有问题的;但如果一个方法 体通过了字节码验证,也仍然不能保证它一定就是安全的。即使字节码验证阶段中进行了再大量、再 严密的检查,也依然不能保证这一点。

2.1.4、符号引用验证

        最后一个阶段的校验行为发生在虚拟机将符号引用转化为直接引用[3]的时候,这个转化动作将在 连接的第三阶段——解析阶段中发生。符号引用验证可以看作是对类自身以外(常量池中的各种符号 引用)的各类信息进行匹配性校验,通俗来说就是,该类是否缺少或者被禁止访问它依赖的某些外部 类、方法、字段等资源。本阶段通常需要校验下列内容:

  • 符号引用中通过字符串描述的全限定名是否能找到对应的类。
  • 在指定类中是否存在符合方法的字段描述符及简单名称所描述的方法和字段。
  •  .......

 就是检查你写的类内依赖的其他类的信息能不能用,会不会找不到或者没有权限等。

  2.2 准备(Preparation)

        准备阶段是正式为类中定义的变量(静态变量)分配内存并设置类变量的初始值阶段。这些变量所使用的内存再方法区(JKD7即以前用永久代实现,JDK8及以后由元空间实现)。此时这个赋初值并不是我们写的哪些初始化操作,例如 public static int  a = 333;,再准备阶段a的值并不是333,而是0,这里的赋初值是赋零值。

注意:

  1. 这里不包含基本数据类型的字段用 static final 修饰的情况,因为 final 在编译的时候就会分配了。
  2. 注意这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到 Java 堆中
  3. 在这个阶段不会像初始化阶段中那样会有初始化或者代码被执行。

 2.3 解析(Resolution)

        符号引用 :符号引用以一组符号来描述所引用的目标,符号可以是任何 形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引 用的目标并不一定是已经加载到虚拟机内存当中的内容。

       直接引用 :直接引用是可以直接指向目标的指针、相对偏移量或者是一个能 间接定位到目标的句柄。直接引用是和虚拟机实现的内存布局直接相关的,同一个符号引用在不同虚 拟机实例上翻译出来的直接引用一般不会相同。

        所谓解析就是将符号引用转为直接引用。也就是得到类、字段、方法在内存中的指针或者偏移量。因此,可以说,如果直接引用存在,那么可以肯定系统中存在该类、方法或者字段。但只存在符号引用,不能确定系统中一定存在该结构。

3、初始化(Initialization)

        初始化阶段是类加载的最后一个步骤,再之前的加载阶段中处理加载阶段可以用用户子自定义类加载器的方式参与,其他时候都是由JVM自己主导控制的,到了初始化阶段才正式的使用我们自己写的java代码了,再这个阶段有一个执行类构造器方法需要我们去了解:<clinit>()方法,这个给方法并不是我们编写的,而是javac编译器自动生成的。

        <clinit>()方法方法是由编译器自动收集类中所有的类变量(static)的赋值动作和静态语句块合并而成的。

那类什么是进行初始化呢(以下情况都是还未被初始化)?

  • 使用new关键字实例化对象的时候。
  • 读取或设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候。
  • 调用一个类型的静态方法的时候。
  • 使用java.lang.reflect包的方法对类型进行反射调用的时候。如果类型没有进行过初始化,则需 要先触发其初始化。
  • 当初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
  • 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先 初始化这个主类。
  • 当使用JDK 7新加入的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解 析结果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四种类型的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。
  • 当一个接口中定义了JDK 8新加入的默认方法(被default关键字修饰的接口方法)时,如果有 这个接口的实现类发生了初始化,那该接口要在其之前被初始化。

并不是只要这个类的代码出现就一定会被初始化,当被动使用时就不会出现初始化。

  • 子类调用父类的静态字段,不会引起子类的初始化。
  • 当有数组(People[] a = new People();)初始化时,他并不会初始化,而是一个虚拟机自动生成的数组类进行初始化。
  • 引用定义再某个类内的常量(被static final修饰)的,也不会引起这个类的初始化,因为这个常量再编译阶段就已经存入调用类的常量池中了。

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

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

相关文章

QWidget: Must construct a QApplication before a QWidget 20:10:25: 程序异常结束。

如果你在Windows上混合并匹配了Release和Debug的dll&#xff0c;则会导致这种情况。我的链接的库是release的版本&#xff0c;也就是qwt.dll&#xff0c;但是点击Qt Creator的运行按钮默认是debug启动&#xff0c;所以报错了&#xff0c;Qt Creator运行按钮里选择release就可以…

重构改善既有代码的设计-学习(一):封装

1、封装记录&#xff08;Encapsulate Record&#xff09; 一些记录性结构&#xff08;例如hash、map、hashmap、dictionary等&#xff09;&#xff0c;一条记录上持有什么字段往往不够直观。如果其使用范围比较宽&#xff0c;这个问题往往会造成许多困扰。所以&#xff0c;记录…

【Linux系统编程二十八】基于条件变量的阻塞队列(生产消费模型)

【Linux系统编程二十八】基于条件变量的阻塞队列(生产消费模型&#xff09; 一.同步问题二.条件变量1.实现原理2.等待的前提3.使用接口①.【定义条件变量】②.【初始化条件变量】③.【让线程去条件变量下等待】④.【为什么第二个参数是锁&#xff1f;】条件变量和锁的关系是什么…

【开源】基于JAVA语言的软件学院思政案例库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理员2.2 普通教师 三、系统展示四、核心代码4.1 查询思政案例4.2 审核思政案例4.3 查询思政课程4.4 思政案例点赞4.5 新增思政案例评语 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的软件学…

Java根据模板文件生成excel文件,同时将excel文件转换成图片

需求 需要将指定数据导出成表格样式的图片&#xff0c;如图 业务拆解 定义一个导出模板将得到的数据填入模板中&#xff0c;生成excel文件将ecxel文件转换成png格式的图片 代码实现 需要引入的依赖 <dependency><groupId>cn.hutool</groupId><artif…

【JavaEE】_基于UDP实现网络通信

目录 1. 服务器 1.1 实现逻辑 1.2 代码 1.3 部分代码解释 2. 客户端 2.1 实现逻辑 2.2 代码 2.3 客户端部分代码解释 3. 程序运行结果 4. 服务器客户端交互逻辑 此篇内容为实现UDP版本的回显服务器echo server&#xff1b; 普通服务器&#xff1a;收到请求&#xff…

Docker搭建MySQL主从数据库-亲测有效

1、测试环境概述 1、使用MySQL5.7.35版本 2、使用Centos7操作系统 3、使用Docker20版本 案例中描述了整个测试的详细过程 2、安装Docker 2.1、如果已经安装docker,可以先卸载 yum remove -y docker \ docker-client \ docker-client-latest \ docker-common \ docker-l…

机器人电机综述 — 电机分类、舵机、步进与伺服、物理性质和伺服控制系统

电机综述 图片与部分素材来自知乎大佬不看后悔&#xff01;最全的电机分类&#xff0c;看这一篇就够了&#xff01; - 知乎 (zhihu.com)&#xff0c;本文只是把机器人中常用的电机知识提炼了一下 1 按照结构和工作原理划分 1. 同步电机 ​ 电机的转速与定子磁场的转速相同步…

线性表的案例引入 | 稀疏多项式的运算

#include <iostream> using namespace std;#define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2typedef int Status;// 定义单链表 typedef struct PNode {float coef; //系数int expn; //指数struct PNode *nex…

基于深度学习的细胞感染性识别与判定

基于深度学习的细胞感染性识别与判定 基于深度学习的细胞感染性识别与判定引言项目背景项目意义项目实施数据采集与预处理模型选择与训练模型评估与优化 结果与展望结论 基于深度学习的细胞感染性识别与判定 引言 随着深度学习技术的不断发展&#xff0c;其在医学图像处理领域…

【UEFI基础】EDK网络框架(UDP4)

UDP4 UDP4协议说明 UDP的全称是User Datagram Protocol&#xff0c;它不提供复杂的控制机制&#xff0c;仅利用IP提供面向无连接的通信服务。它将上层应用程序发来的数据在收到的那一刻&#xff0c;立即按照原样发送到网络。 UDP报文格式&#xff1a; 各个参数说明如下&…

基础+常用的数据结构

基础 java基础 JDK 和 JRE JDK&#xff0c;它是功能齐全的 Java SDK&#xff0c;是提供给开发者使用&#xff0c;能够创建和编译 Java 程序的开发套件。它包含了 JRE,同时还包含了编译 java 源码的编译器 javac 以及一些其他工具比如 javadoc&#xff08;文档注释工具&#…

舵机使用总结

文章目录 1 舵机简介2 注意事项3 编写驱动程序3.1 使用STM32作为控制器3.1.1 计算高电平对应程序中的取值范围3.1.2 编写控制程序 1 舵机简介 舵机使用PWM控制&#xff0c;周期为20ms&#xff0c;通过改变高电平占空比来驱动&#xff0c;高电平通常为1~2ms&#xff08; 或 0.5 …

Find My卡片正成为消费电子香饽饽,伦茨科技ST17H6x可以帮到您

今年CES许多公司发布支持苹果Find My的卡片产品&#xff0c;这种产品轻薄可充电&#xff0c;放在钱包、背包或者手提包可以防丢查找&#xff0c;在智能化加持下&#xff0c;防丢卡片使得人们日益关心自行车的去向。最新的防丢卡片与苹果Find My结合&#xff0c;智能防丢&#x…

vue生命周期图示

详见&#xff1a;官网介绍

聊聊Java虚拟机(一)—— 类加载子系统

1. 前言 ​ 虚拟机就是一款用来执行虚拟计算机指令的计算机软件。它相当于一台虚拟计算机。大体上&#xff0c;虚拟机分为系统虚拟机和程序虚拟机。系统虚拟机就相当于一台物理电脑&#xff0c;里面可以安装操作系统&#xff1b;程序虚拟机是为了执行单个计算机程序而设计出来…

海外媒体发稿:出口贸易媒体发稿推广8种方式让您事半功倍-华媒舍

出口贸易已成为越来越多企业的发展方向。要让更多潜在客户了解并选择你的产品&#xff0c;仅靠传统的销售手段已远远不够。作为一名出口贸易从业人员&#xff0c;如何利用媒体发稿推广&#xff0c;事半功倍地扩大市场影响&#xff0c;成为摆在我们面前的一大任务。本文将为您介…

Vulnhub-TECH_SUPP0RT: 1渗透

文章目录 一、前言1、靶机ip配置2、渗透目标3、渗透概括 开始实战一、信息获取二、使用smb服务获取信息三、密码破解四、获取webshell五、反弹shell六、web配置文件获取信息七、提权 一、前言 由于在做靶机的时候&#xff0c;涉及到的渗透思路是非常的广泛&#xff0c;所以在写…

【c++】C++输入输出

C输入&输出 新生婴儿会以自己独特的方式向这个崭新的世界打招呼&#xff0c;C刚出来后&#xff0c;也算是一个新事物&#xff0c;那C是否也应该向这个美好的世界来声问候呢&#xff1f;我们来看下C是如何来实现问候的 #include<iostream> // std是C标准库的命名空间名…

全网最高质量文章:重新学习Java中的HashMap!!

前言 本文参考了美团技术团队的科普文章Java 8系列之重新认识HashMap - 知乎 (zhihu.com) 这篇文章的质量极其高&#xff0c;高到很有可能是全网介绍HashMap这个知识点最优秀的文章&#xff0c;没有之一&#xff01;&#xff01;&#xff01;因此&#xff0c;我决定在我自己的…