JVM 虚拟机的编译器、类加载过程、类加载器有哪些?

news2024/9/20 6:52:06

JVM 虚拟机的编译器

编译器可以分为:前端编译器、JIT 编译器、AOT编译器

img

前端编译器:源代码 --> 字节码

在Java语言中,JDK安装目录中的javac就是编译器。它负责将Java源代码编译为字节码。因为处于编译的前期,javac也叫做前端编译器。

img

JIT 编译器:字节码 --> 机器码

即时编译器(Just-In-Time Compiler,JIT)

Java源代码转化为 字节码之后,要运行它,有两种选择:

  1. 使用 Java 解释器,执行字节码。
  2. 使用 JIT(Just-In-Time Compiler) 编译器 将字节码 转化为 机器码。

img

JIT 编译器在程序运行时,对频繁执行的字节码进行即时编译,将其转换为本地机器码,从而提高程序的执行效率

HotSpot 虚拟机的两个即时编译器

在 HotSpot 虚拟机内置了两个即时编译器,分别称为 Client CompilerServer Compiler。这两种不同的编译器衍生出两种不同的编译模式,我们分别称之为:C1 编译模式C2 编译模式

  • C1 编译模式会将字节码编译为本地代码,进行简单、可靠的优化,如有必要将加入性能监控的逻辑。
  • C2 编译模式,也是将字节码编译为本地代码,但是会启用一些编译耗时较长的优化,甚至会根据性能监控信息进行一些不可靠的激进优化。

AOT 编译器:源代码 --> 机器码

提前编译器(Ahead-of-Time Compiler,AOT)

AOT 编译器的基本思想是:在程序执行前生成 Java 方法的本地代码,以便在程序运行时直接使用本地代码

HotSpot 虚拟机的三种运行模式

注意,对于 HotSpot 虚拟机来说,其一共有三种运行模式可选,分别是:

  • 混合模式(Mixed Mode) 。即 C1 和 C2 两种模式混合起来使用,这是默认的运行模式。如果你想单独使用 C1 模式或 C2 模式,使用 -client-server 打开即可。
  • 解释模式(Interpreted Mode)。即所有代码都解释执行,使用 -Xint 参数可以打开这个模式。
  • 编译模式(Compiled Mode)。 此模式优先采用编译,但是无法编译时也会解释执行,使用 -Xcomp 打开这种模式。

在命令行中输入 java -version 可以看到,我机器上的虚拟机使用 Mixed Mode 运行模式。

image.png

JVM 虚拟机类加载过程

Java 中的类加载过程分为:加载(Loading)链接(Linking)初始化(Initialization)
在这里插入图片描述

  1. 加载(Loading):阶段的目的是将类的.class文件加载到JVM中。在这个阶段,JVM 会根据类的全限定名来获取定义该类的二进制字节流,并将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

  2. 链接(Linking):又分为 验证(Verification)准备(Prepartion)解析(Resolution)

    1. 验证:校验类的正确性,包括:
      1. 文件格式验证:验证字节流是否符合Class文件格式的规范。比如,是否以0xCAFEBABE开头。
      2. 元数据验证:对字节码描述进行语义分析,是否遵循Java规范。比如一个类是否继承了多个类。
      3. 字节码验证:比如验证指令代码序列是否能够正常工作。
      4. 符号引用验证:确保解析动作能够正确执行。
    2. 准备:给 类中定义的变量(被static修饰的静态变量)分配内存,并设置初始值。
    3. 解析:虚拟机将 常量池 内的 符号引用 替换为 直接引用。(解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符 7 类符号引用进行)
  3. 初始化(Initialization):初始化阶段是执行初始化方法 <clinit>()方法的过程,是类加载的最后一步,这一步 JVM 才开始真正执行类中定义的 Java 程序代码(字节码)。

    对于初始化阶段,有些情况必须立即初始化(如下)。其他情况,则是进行懒加载(首次用到的时候才初始化)

    1. 遇到newgetstaticputstaticinvokestatic这四条字节码指令时,会立即初始化。
    2. 使用反射机制时,立即初始化。
    3. 初始化一个类时,其父类没初始化,则会立即初始化父类。
  4. 卸载(Unloading):对象被垃圾回收。

类加载器

类加载器 主要作用于 JVM 虚拟机类加载过程中的 加载阶段。

如何比较两个类是否“相等”

对于任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性。所以:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个 Class文件,被同一个Java虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相等

双亲委派机制

站在JAVA虚拟机的角度来讲,只存在两种不同的类加载器:

  1. 一种是启动类加载器(Bootstrap ClassLoader,这个类加载器使用C++语言实现,是虚拟机自身的一部分
  2. 另外一种就是其他所有的类加载器,这些类加载器都由Java语言实现,独立存在于虚拟机外部,并且全都继承自抽象类 java.lang.ClassLoader

每一个类都有一个对应它的类加载器。系统中的 ClassLoader 在协同工作的时候会默认使用 双亲委派模型。其工作过程为:

  • 当一个类加载器收到了类加载的请求,不会自己去加载这个类,而是委派给父类加载器完成。
  • 只有当父类加载器无法完成这个加载请求时(它搜索范围中没找到对应的类信息),子加载器才会尝试自己去完成加载。

在这里插入图片描述

父类加载器

双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载器

三层类加载器

双亲委派机制中的主要的三层类加载器,他们分别是:启动类加载器、扩展类加载器、应用程序类加载器

  • BootstrapClassLoader(启动类加载器) :最顶层的加载类,由 C++实现,负责加载 %JAVA_HOME%/lib目录下的 jar 包和类,或者被 -Xbootclasspath参数指定的路径中的所有类。
  • ExtensionClassLoader(扩展类加载器) :主要负责加载 %JRE_HOME%/lib/ext 目录下的 jar 包和类,或被 java.ext.dirs 系统变量所指定的路径下的 jar 包。
  • AppClassLoader(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。

双亲委派机制的好处

双亲委派模型保证了 Java 程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类)。

如何破坏双亲委派机制

答:有如下几种方法:

  1. 通过自定义类加载器,重写loadClass()方法,可以改变这种默认的加载顺序,从而破坏双亲委派机制。

    比如,可以先尝试从自己指定的路径去加载类,如果找不到再调用父类的loadClass方法。

  2. 线程上下文类加载器:当 JVM 需要加载类且当前类加载器无法完成时,会尝试使用线程上下文类加载器,从而绕过双亲委派机制从特定类加载器加载类。

线程上下文类加载器

在双亲委托模型下,类的加载是由下至上的,即下层的类加载器会委托上层进行加载。

但对于SPI来说,有些接口是Java核心库所提供的,而Java核心库是由启动类加载器来加载的,而这些接口的实现却来自不同的Jar包(厂商提供JDBC的实现有Oracle,MySQL等), Java的启动类加载器不会加载其他来源的jar包,这样传统的双亲委托模型就无法满足SPI的要求而通过给当前线程设置上下文类加载器,就可以由设置的上下文类加载器来实现对于接口实现类的加载

SPI(Service Provider Interface)即服务提供者接口

  • SPI 是一种用于实现框架扩展和插件化的机制。它定义了一组接口,允许第三方为这些接口提供具体的实现。
  • 例如,Java 的数据库连接(JDBC)就是一个典型的 SPI 应用。JDBC 定义了一组用于与数据库进行交互的接口,而不同的数据库厂商提供了各自的实现。

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

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

相关文章

C语言 | Leetcode C语言题解之第417题太平洋大西洋水流问题

题目&#xff1a; 题解&#xff1a; static const int dirs[4][2] {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};void bfs(int row, int col, bool ** ocean, const int ** heights, int m, int n) {if (ocean[row][col]) {return;}ocean[row][col] true;int * queue (int *)malloc…

如何安装和注册 GitLab Runner

如何安装和注册 GitLab Runner GitLab Runner 是一个用于运行 GitLab CI/CD (Continuous Integration/Continuous Deployment) 作业。它是一个与 GitLab 配合使用的应用程序&#xff0c;可以在本地或云中运行。Runner 可以执行不同类型的作业&#xff0c;例如编译代码、运行测…

有效安全计划评估的基本指标

衡量安全计划成功与否的最有效指标是什么&#xff1f; 最直接的指标是&#xff1a;您的组织是否遭到入侵&#xff1f;如果答案是肯定的&#xff0c;那么显然还有工作要做。如果答案是否定的&#xff0c;那么您的状况就更好了——但情况比这更复杂。 即使您没有遭到入侵&#…

视频理解大模型最新进展

文章目录 Video-LLaMAVision-Language BranchAudio-Language Branch Video-ChatGPTMiniGPT4-videoCogVLM2-Video&#xff08;1&#xff09;Pre-training&#xff08;2&#xff09;Post-training Qwen2-VLMA-LMMChat-UniVi大模型对比 Video-LLaMA 2023&#xff1a;阿里达摩院的…

JAVA虚拟机----JVM

(一)认识JVM JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运⾏在⼀个完全隔离的环境中的完整计算机系统。 常⻅的虚拟机&#xff1a;JVM、VMwave、Virtual Box。 &#xff08;二&#xff09;JVM运…

2017年国赛高教杯数学建模C题颜色与物质浓度辨识解题全过程文档及程序

2017年国赛高教杯数学建模 C题 颜色与物质浓度辨识 比色法是目前常用的一种检测物质浓度的方法&#xff0c;即把待测物质制备成溶液后滴在特定的白色试纸表面&#xff0c;等其充分反应以后获得一张有颜色的试纸&#xff0c;再把该颜色试纸与一个标准比色卡进行对比&#xff0c…

如何查看电脑什么时候被人动过及看过的文件?

一、查看Windows事件查看器 Windows系统具有强大的日志记录功能&#xff0c;通过“事件查看器”可以查看电脑的使用记录。具体步骤如下&#xff1a; 按下Win R组合键打开运行窗口&#xff0c;输入eventvwr.msc命令并回车&#xff0c;打开事件查看器。 在事件查看器中&#x…

solidwork镜像实体

效果如下&#xff1a; 可以看到这两条线是对称的。 第一步&#xff0c;点击这条要镜像的边&#xff0c;接着点击镜像实体。 然后选择镜像轴&#xff0c;即可

OpenHarmony标准系统mipi摄像头适配

OpenHarmony标准系统mipi摄像头适配 本文档以rk3568为例&#xff0c;讲述如何在OpenHarmony 标准系统rk设备上适配mipi摄像头。 开发环境 OpenHarmony标准系统4.1rrk3568设备摄像头ov5648,ov8858 文档约定&#xff1a;4.1r_3568为OpenHarmony标准系统源码根目录 1.适配准备:得…

苹果CMS插件:优化蜘蛛访问内容,提升百度收录率

确保蜘蛛抓取原始内容 专为苹果CMS设计的广告管理插件&#xff0c;能够智能识别搜索引擎蜘蛛与普通访客&#xff0c;确保蜘蛛访问时展示原始内容&#xff0c;从而提升被百度等搜索引擎收录的几率。 广告显示提升收益 对于普通访客&#xff0c;该插件则优先显示广告内容&#…

UnLua扩展C++函数和蓝图自定义事件

一、通过BlueprintImplementableEvent标记扩展C函数 1、 这个标记表示C不需要实现&#xff0c;让蓝图/Lua重写。 2、首先在C中将LuaImp函数标记为BlueprintImplementableEvent&#xff0c;不需要实现&#xff0c;然后再GetIndex中调用该函数。 MyBaseActor.h UFUNCTION(Bluepr…

电力电塔电线缺陷检测数据集 voc yolo

电力 电塔电线缺陷检测数据集 10000张 带标注 voc yolo 电力电塔电线缺陷检测数据集 数据集描述 该数据集旨在用于电力电塔和电线的缺陷检测任务&#xff0c;涵盖多种常见的缺陷类型。数据集包含了大量的图像及其对应的标注信息&#xff0c;可用于训练计算机视觉模型&#x…

DEPLOT: One-shot visual language reasoning by plot-to-table translation论文阅读

文章链接&#xff1a;https://arxiv.org/abs/2308.01979http://arxiv.org/abs/2212.10505https://arxiv.org/abs/2308.01979 源码链接&#xff1a;https://github.com/cse-ai-lab/RealCQA Abstract 理解图表需要很强的推理能力&#xff0c;之前的最先进 &#xff08;SOTA&…

圆周阵列元件的间距增加操作方法

在进行器件圆周阵列时&#xff0c;内圈的角度和外圈的旋转角度都相同&#xff0c;由于内圈的圆周长小于外圈的圆周长&#xff0c;有可能在内圈造成部分元件之间有两个焊盘会有覆盖的情况&#xff0c;此时需要对内圈的元件位置进行微调&#xff0c;需要增加在同一半径位置的元件…

数据结构 ——— 算法的时间复杂度

目录 时间复杂度的概念 时间复杂度函数式 大O的渐进表示法的概念 大O的渐进表示法 时间复杂度的概念 在计算机科学中&#xff0c;算法的时间复杂度是一个函数&#xff08;数学上的函数式&#xff09;&#xff0c;它定量描述了该算法的运行时间&#xff0c;一个算法执行所耗…

Netty笔记10-Netty参数调优

文章目录 一、CONNECT_TIMEOUT_MILLISCONNECT_TIMEOUT_MILLIS设置为1秒超时CONNECT_TIMEOUT_MILLIS设置为5秒超时注意事项 二、SO_BACKLOG代码示例注意事项 三、ulimit -n(文件描述符)设置文件描述符限制在注意事项 四、TCP_NODELAY使用 TCP_NODELAY 的场景注意事项 五、SO_SND…

软件安全最佳实践:首先关注的地方

尽管组织拥有大量可用的工具&#xff0c;但应用程序安全性仍然不足。 最近的数据显示&#xff0c;在过去四到五年中&#xff0c;软件供应链攻击同比增长了 600-700%&#xff0c;超过一半的美国企业在过去 12 个月中遭受过某种形式的软件供应链攻击。 为何应用程序安全工作未…

签署《AI安全国际对话威尼斯共识》 智源持续推动人工智能安全发展

近日&#xff0c;由AI安全国际论坛&#xff08;Safe AI Forum&#xff09;和博古睿研究院&#xff08;Berggruen Institute) 共同举办的第三届国际AI安全对话&#xff08;International Dialogues on AI Safety&#xff09;在威尼斯举办。图灵奖得主Yoshua Bengio、姚期智教授&…

电气设备施工现场风险状态判断ai模型训练数据集

电气设备施工现场风险状态判断ai模型训练数据集 id:18 电气设备施工现场工人人工智能学习数据和工作环境安全数据&#xff0c;建立系统化管理体系&#xff0c;改变全球EHS范式&#xff0c;预防工业事故。数据集记录了387709例子电力设施建设以及施工现场相关的灾害安全环境数据…

VM16安装macOS11

注意&#xff1a; 本文内容于 2024-09-17 12:08:24 创建&#xff0c;可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容&#xff0c;请访问原文地址&#xff1a;VM16安装macOS11。感谢您的关注与支持&#xff01; 使用 Vmware Workstation Pro 16 安装 macOS…