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修饰)的,也不会引起这个类的初始化,因为这个常量再编译阶段就已经存入调用类的常量池中了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue2 点击按钮下载文件保存到本地(后台返回的zip压缩流)

// import ./mock/index.js; // 该项目所有请求使用mockjs模拟 去掉mock页面url下载 console.log(res, res)//token 是使页面不用去登录了if (res.file) {window.location.href Vue.prototype.$config.VUE_APP_BASE_IDSWAPI Vue.prototype.$config.VUE_APP_IDSW /service/mode…

VRPSolverEasy:支持VRP问题快速建模的精确算法Python包

文章目录 前言一步步安装免费版主要模块介绍1. depot point2. customer point3. links4. vehicle type VRPTW 算例数据说明模型建立输出求解状态及结果 前言 VRPSolverEasy 是用于车辆路径问题&#xff08;VRP&#xff09;的最先进的分支切割和定价算法求解器1&#xff0c;它的…

基于Servlet建立表白墙网站

目录 一、设计思想 二、设计表白墙页面&#xff08;前端--VSCode&#xff09; 1、效果图 2、html部分&#xff08;网页上有哪些内容&#xff09; 3、css部分&#xff08;页面内容的具体样式&#xff09; 4、js部分&#xff08;页面行为&#xff09; 三、借助Servlet实现客…

攻防世界——Mysterious

运行就是一个要你输入的题型&#xff0c;这种题我们要么得到password&#xff0c;要么直接不管这个得到flag int __stdcall sub_401090(HWND hWnd, int a2, int a3, int a4) {int v4; // eaxchar Source[260]; // [esp50h] [ebp-310h] BYREF_BYTE Text[257]; // [esp154h] [eb…

4.postman批量运行及json、cvs文件运行

一、批量运行collection 1.各个接口设置信息已保存&#xff0c;在collection中点击run collection 2.编辑并运行集合 集合运行时&#xff0c;单独上传图片时报错。需修改postman设置 二、csv文件运行 可新建记事本&#xff0c;输入测试数据&#xff0c;后另存为新的文本文件&…

call_once 单例模式 Singleton / condition_variable 与其使用场景

一、call_once 单例模式 Singleton 大家可以先看这篇文章&#xff1a;https://zh.cppreference.com/w/cpp/thread/call_once /*std::call_oncevoid call_once( std::once_flag& flag, Callable&& f, Args&&... args ); */ #include <iostream> #i…

【算法与数据结构】474、LeetCode一和零

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题要找strs数组的最大子集&#xff0c;这个子集最多含有 m m m个0和 n n n个1。本题也可以抽象成一个…

云仓酒庄的品牌雷盛红酒LEESON分享从事酒行业有前途吗?

化在全球都有着悠久的传承文化&#xff0c;每逢传统节日&#xff0c;新朋好友相聚庆贺&#xff0c;酒在好多场合都是不可或缺的选项。酒的消费群体也是十分庞大&#xff0c;有不少朋友问云仓酒庄&#xff0c;从事酒的行业能不能挣钱&#xff0c;有没有前途&#xff1f;回答好这…

【Qt之模型视图】1. 模型和视图架构

1. 模型/视图架构是什么及有什么用 MVC&#xff08;Model-View-Control&#xff09;是一种源自Smalltalk的设计模式&#xff0c;通常用于构建用户界面。 MVC由三种类型的对象组成。模型是应用对象&#xff0c;用来表示数据&#xff1b;视图是模型的用户界面&#xff0c;用来显…

Windows 拦截系统睡眠、休眠

前言 在前一篇文章中&#xff0c;我们分析了以编程方式拦截 Winlogon 相关回调过程的具体做法&#xff0c;我们给出了一种拦截 RPC 异步回调的新方法——通过过滤特征码&#xff0c;我们可以对很多系统热键以及跟电源有关的操作做出“提前”响应。但是我们给出的代码并不能真正…

代码随想录第十八天 513 找树左下角的值 112 路径之和 106 从中序与后序遍历序列构造二叉树

LeetCode 513 找树左下角的值 题目描述 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 思路 1.确定递…

matlab appdesigner系列-常用14-树(复选框)

之前系列常用9&#xff0c;为单个复选框。树&#xff0c;就是多个复选框形成的选项组 示例&#xff1a;列举湖北省的几个城市 湖北省 武汉 宜昌 襄阳 荆州 1&#xff09;将树&#xff08;复选框&#xff09;拖拽到画布上&#xff0c;方式1就是&#xff1a;文字可以在右侧…

课题学习(十九)----Allan方差:陀螺仪噪声分析

一、介绍 Allan方差是一种分析时域数据序列的方法&#xff0c;用于测量振荡器的频率稳定性。该方法还可用于确定系统中作为平均时间函数的本征噪声。该方法易于计算和理解&#xff0c;是目前最流行的识别和量化惯性传感器数据中存在的不同噪声项的方法之一。该方法的结果与适用…

131. 分割回文串 - 力扣(LeetCode)

问题描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 输入示例 s "aab"输出示例 [["a","a","b"],["…

PS滤镜插件:Adobe Camera Raw 16 for Mac中文激活版

Adobe Camera Raw是Adobe公司开发的一款用于处理数码相机RAW格式文件的软件插件。它可以在Adobe Photoshop、Adobe Bridge和Adobe Lightroom等软件中使用&#xff0c;用于调整RAW文件的曝光、白平衡、对比度、色彩饱和度、锐化等参数&#xff0c;从而得到更好的图像质量。 软件…

STM32之模数转换器(ADC)

一、模数转换器介绍 1、模数转换器简介 为什么使用模拟转换器&#xff1f;&#xff1f; 因为MCU只能识别01010101的数字信号&#xff0c;而外部物理信号均为模拟信号&#xff0c;如声音、光、电等&#xff0c;所以为了让计算机能够处理外部物理的信息&#xff0c;必须要通过…

增加CO气体报警、氢气报警以及烟雾报警

标题&#xff1a;增加CO气体报警、氢气报警以及烟雾报警。 内容&#xff1a;通过ADC采集通道&#xff0c;实现传感器电压的采集&#xff0c;通过对电压进行判断是否报警&#xff0c;&#xff08;理论上应该可以计算出气体浓度&#xff0c;通过气体浓度来判断是否报警&#xff…

入门分布式事务,2PC 3PC

分布式事务 什么是分布式一致性 在分布式系统中&#xff0c;为了保证数据的高可用&#xff0c;通常&#xff0c;我们会将数据保留多个副本(replica)&#xff0c;这些副本会放置在不同的物理的机器上。为了对用户提供正确的增\删\改\查等语义&#xff0c;我们需要保证这些放置…

VRRP协议负载分担

VRRP流量负载分担 VRRP负载分担与VRRP主备备份的基本原理和报文协商过程都是相同的。同样对于每一个VRRP备份组,都包含一个Master设备和若干Backup设备。与主备备份方式不同点在于:负载分担方式需要建立多个VRRP备份组,各备份组的Master设备可以不同;同一台VRRP设备可以加…

骑砍战团MOD开发(39)-RTS塔防保卫卡拉迪亚大陆

骑砍1战团mod开发-RTS塔防保卫卡拉迪亚大陆_哔哩哔哩bilibili_骑马与砍杀https://www.bilibili.com/video/BV1hw411E7bP/骑砍战团MOD开发(28)-骑砍联盟之RTS大规模军团竞技-CSDN博客文章浏览阅读369次&#xff0c;点赞11次&#xff0c;收藏7次。【代码】骑砍战团MOD开发(28)-骑…