当前位置: 首页 > news >正文

JVM -- 类加载器

类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现访问接口和类字节码数据的技术。类加载器只负责加载过程中的字节码获取并加载到内存的这一过程。
在这里插入图片描述

一、 类加载器的分类

在这里插入图片描述
类加载器的详细信息可以使用Arthas通过classloader命令查看:
在这里插入图片描述

1.启动类加载器(Bootstrap ClassLoader)

由Hotspot虚拟机提供的,使用C++编写的类加载器,默认加载Java安装目录/jre/lib下的类文件。针对用户自定义的jar包如果想被启动类加载器加载的话,可以使用如下参数进行加载:

-Xbootclasspath/a:jar包目录/jar包名

加载java中最核心的类。

2. 扩展类加载器(Extension Class Loader)

使用JAVA编写,由JDK提供,源码位于sun.misc.Launcher,是一个静态内部类,继承自URLClassLoader。默认加载java安装目录的/jre/lib/ext下的文件,使用如下参数使用扩展类加载器进行加载:

-Djava.ext.dirs=jar包目录 进行扩展,这种方 式会覆盖掉原始目录,可以用;(windows):(macos/linux) 追加上原始目录

在这里插入图片描述

3. 应用类加载器(App CLass Loader)

使用JAVA编写,由JDK提供,源码位于sun.misc.Launcher,是一个静态内部类,继承自URLClassLoader。加载的是位于classpath下的文件

二、 双亲委派机制

请添加图片描述

双亲委派机制主要是为了解决:

  1. 同一个类被多次加载或者一个类应该被谁加载的问题;
  2. 保证类加载的安全性:避免恶意代码替换JDK中的核心类库。

在这里插入图片描述
启动类加载器、扩展类加载器、应用类加载器的关系如下:
在这里插入图片描述

[arthas@106672]$ classloader -t
+-BootstrapClassLoader+-sun.misc.Launcher$ExtClassLoader@79acc872                                                                                                                                +-com.taobao.arthas.agent.ArthasClassloader@7b94591c+-sun.misc.Launcher$AppClassLoader@18b4aac2

应用程序类加载器的父类是扩展类加载器。而扩展类加载器的parent为null,但是在逻辑上,扩展类加载器依然会把启动类加载器当作夫类加载器处理。
启动类加载器使用C++编写,没有父类加载器。

逻辑:当一个类去加载某个类的时候,会自底向上查找是否加载过,如果加载过就直接返回,如果到底一直没有加载过,再由顶向下委派进行加载。
在这里插入图片描述

三、 打破双亲委派机制

打破的原因:一个Tomcat可以部署多个Web应用,如果两个应用中出现了相同限定名的类,比如Servlet类,Tomcat要保证这两个类都能加载并且它们应该是不同的类。

ClassLoader类中实现双线委派方式原理:

在这里插入图片描述
双亲委派的核心代码:

try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}
} catch (ClassNotFoundException e) {if (c == null) {// If still not found, then invoke findClass in order to find the class.long t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statessun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();
}

请添加图片描述

1. 自定义类加载器

自定义类加载器,重写loadClass(),不再使用双亲委派机制,而使用自己实现的loadClass()。
其中自定义类加载器的父加载器为:应用类加载器(getSystemClassLoader())

问题:两个自定义类加载器加载相同限定名的类,是否会冲突?

不会,只有同一个类加载器且加载相同限定名的才会被认定为同一个类。

在这里插入图片描述

2. 线程上下文类加载器

以DriverManager为例:

核心逻辑就是:启动类加载器加载DriverManager,在初始化DriverManager时会通过SPI机制加载mysql驱动,SPI机制利用了线程上下文来加载并创建对象,实现原本应该由启动类加载器交由应用类加载器去加载的过程,打破双亲委派机制。

依赖于SPI机制:rt.jar核心包是有Bootstrap类加载器加载的,其内包含SPI核心接口类,由于SPI中的类经常需要调用外部实现类的方法,而jdbc.jar包含外部实现类(jdbc.jar存在于classpath路径)无法通过Bootstrap类加载器加载,因此只能委派线程上下文加载器的加载方式破坏了“双亲委派模型”,它在执行过程中抛弃双亲委派加载链模式,使程序可以逆向使用类加载器,当然这也使得Java类加载器变得更加灵活。为了进一步证实这种场景,不妨看看DriverManager类的源码,DriverManager是Java核心rt.jar包中的类,该类用来管理不同数据库的实现驱动即Driver,它们都实现了Java核心包中的java.sql.Driver接口,如mysql驱动包中的com.mysql.jdbc.Driver

AccessController.doPrivileged(new PrivilegedAction<Void>() {public void run() {ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);Iterator<Driver> driversIterator = loadedDrivers.iterator();}
}

实现延迟服务提供者查找
DriverManager.loadInitialDrivers -> ServiceLoader.load -> reload ->lookupIterator = new LazyInterator(service, loader);
加载meta-inf,初始化驱动
loadedDrivers.iterator() -> driversIterator.hasNext() -> hasNextService ->
ClassLoader.getSystemResources(fullName);

这样ServiceLoader会帮我们处理一切,并最终通过load()方法加载

3. Osgi框架的类加载器

历史上,OSGi模块化框架。它存在同级之间的类加载器的委托加载(如下图的加载器1和2)。OSGi还使用类加载器实现了热部署的功能。热部署指的是在服务不停止的情况下,动态地更新字节码文件到内存中。JDK9之后不再使用OSGi,现在可以使用arthas解决热部署问题。

在这里插入图片描述
由于这种机制使用已经不多,所以不再过多讨论OSGI

相关文章:

JVM -- 类加载器

类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现访问接口和类字节码数据的技术。类加载器只负责加载过程中的字节码获取并加载到内存的这一过程。 一、 类加载器的分类 类加载器的详细信息可以使用Arthas通过classloader命令查看&#xff1a; 1.启动类加载器(Boots…...

OLAP引擎之StarRocks

StarRocks 是一款新兴的开源分布式实时分析型数据库&#xff0c;专为高性能、高并发的数据分析场景设计。它结合了传统数据仓库和大数据技术的优势&#xff0c;提供了强大的实时数据处理和分析能力。以下是对 StarRocks 的详细介绍&#xff0c;涵盖其基本概念、核心特性、架构设…...

基于微信小程序的小区业主服务系统(源码+论文+部署讲解等)

博主介绍&#xff1a;✌全网粉丝10W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术栈介绍&#xff1a;我是程序员阿龙&#xff…...

C++ | Leetcode C++题解之第327题区间和的个数

题目&#xff1a; 题解&#xff1a; class Solution { public:int countRangeSumRecursive(vector<long>& sum, int lower, int upper, int left, int right) {if (left right) {return 0;} else {int mid (left right) / 2;int n1 countRangeSumRecursive(sum,…...

C# Winform 多窗体切换方式一

一、简介 在 Winform 开发中&#xff0c;多窗体的切换是一个常见的需求&#xff0c;比如登录成功后&#xff0c;切换至主界面&#xff0c;在网上查阅相关的资料&#xff0c;你会发现很多都是用 form2.Show(); this.Hide(); 这种方式&#xff0c;这种方式也存在一些问题&#…...

笔记本CPU天梯图(2024年8月),含AMD/骁龙等新CPU

原文地址&#xff08;高清无水印原图/持续更新/含榜单出处链接&#xff09;&#xff1a; 2024年8月笔记本CPU天梯图 2024年8月笔记本CPU天梯图 2024年8月5日更新日志&#xff1a;常规更新Cinebench R23、PassMark笔记本CPU天梯图&#xff0c;新增Geekbench 6.2单核多核天梯图&…...

GitLab-CI/CD指南

由于公司没有运维&#xff0c;写go服务时各个环境编译部署还是略显麻烦&#xff0c;由于代码管理使用的是 gitlab&#xff0c;所以决定使用 gitlab 自带的 CI/CD 来做自动编译和部署&#xff0c;这样每次提交代码以后就可以自动部署到服务器上了。 gitlab 本身只有 CI/CD 的接…...

io目录操作学习

1、基本概念 目录也是一种文件&#xff0c;因此操作流程与普通文件类似&#xff0c;有诸如打开、关闭、定位等概念&#xff0c;但目录是一种特殊的文件&#xff0c;目录存储的数据的最小单位并不是字符&#xff0c;而是目录项。这使得目录跟普通文件又有区别。 在Linux中&…...

Ant-Design-Vue

Ant-Design-Vue是蚂蚁金服Ant Design官方推荐的Vue版UI组件库&#xff0c;它继承了Ant Design的设计语言和Vue.js的易用性&#xff0c;为开发者提供了丰富、高质量的Vue组件&#xff0c;极大地简化了前端开发流程。以下是一份详细的Ant-Design-Vue快速上手指南及排坑建议&#…...

2024互联网暑期实习面经和流程记录分享

2024互联网暑期实习面经和流程记录分享 面试经验和流程需要注意的点 面试经验和流程 因为敏感信息的原因&#xff0c;这里涉及到公司名字的全部进行打码 笔者投递和面试了很多公司&#xff0c;具体有包括算法和开发岗&#xff0c;下面的公司一律用字母代替。 O公司&#xff0…...

风云崛起之拉氏变换和拉式逆变换

图像的分割写出来了&#xff0c;但是写的不好&#xff0c;暂时先不发了。这两天小y想在把拉式变换的内容写出来&#xff0c;小y最近再看信号和电路&#xff0c;需要复习数学&#xff0c;所以把这点写出来。 首先要推出分布积分的公式&#xff0c;我们知道积分和微分为逆运算&am…...

1、.Net UI框架:WinUI - .Net宣传系列文章

WinUI(Windows UI Library)是微软提供的一个用于构建Windows应用程序的本机UI平台组件。它与Windows应用SDK紧密相关&#xff0c;允许开发者创建适用于Windows 10及更高版本的应用程序&#xff0c;并且可以发布到Microsoft Store。WinUI 3是最新的一代&#xff0c;它提供了与操…...

计算机的错误计算(五十九)

摘要 讨论用 Go语言实现的 函数的计算精度问题。 由计算机的错误计算&#xff08;五十五&#xff09;知&#xff0c;国际 IEEE 754 标准中&#xff0c; 函数具有定义域 . 那么&#xff0c;在常规编程模式下用 Go语言实现这个函数&#xff0c;其输出的精度如何&#xff1f; …...

【数学分析笔记】第1章第1节:集合(1)

作为一个计算机专业的人&#xff0c;想自学一下数学专业的专业课补一补AI基础&#xff0c;顺带写个笔记&#xff0c;听的课是陈纪修版本的数学分析&#xff1a; 1. 集合与映射 1.1 集合 1.1.1 基本概念 集合&#xff1a;由某种特定性质的具体的或抽象的对象汇集的总体。 集…...

计算机毕业设计 校园失物招领网站 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

GIT指令大全详解

目录 GIT指令详解 拉取 提交 分支操作(假设分支为a) 版本回退 主分支拉取到分支 常用的Git指令 一、初始化配置 二、初始化仓库 三、检查当前文件状态 四、添加 五、查看提交历史 六、撤销更改 七、查询 八、分支 九、标签管理 十、其他常用指令 GIT指令详解 Git是一个开源的分…...

ECCV2024,清华百度提出ReSyncer:可实现音频同步嘴唇动作视频生成。

清华&百度等联合提出了ReSyncer&#xff0c;可以实现更高稳定性和质量的口型同步&#xff0c;而且还支持创建虚拟表演者所必需的各种有趣属性&#xff0c;包括快速个性化微调、视频驱动的口型同步、说话风格的转换&#xff0c;甚至换脸。 ReSyncer的工作原理可以简单理解为…...

论文笔记:YOLOv8-QSD 自动驾驶场景小目标检测算法

摘要 YOLOv8-QSD网络是一种新型的无锚点驾驶场景检测网络&#xff0c;建立在YOLOv8的基础上&#xff0c;在保证检测精度的同时保持效率。该网络的骨干网采用结构重参数化技术来转换基于多样化分支块 &#xff08;DBB&#xff09; 的模型。 为了准确检测小目标&#xff0c;它集…...

Vue.js状态管理:Vuex与Pinia的比较

在 Vue.js 生态系统中&#xff0c;状态管理是构建复杂应用时的重要组成部分。Vue.js 提供了两种流行的状态管理库&#xff1a;Vuex 和 Pinia。虽然两者都旨在简化状态管理&#xff0c;但它们在设计哲学、API、性能和易用性方面有所不同。本文将深入探讨 Vuex 和 Pinia 的异同&a…...

OJ题目【栈和队列】

目录 有效的括号 有效的括号【代码】 用队列实现栈 用队列实现栈【代码】 用栈实现队列 用栈实现队列【代码】 设计循环队列 有效的括号 https://leetcode.cn/problems/valid-parentheses/submissions/551394950/ 思路&#xff1a;把左括号放到栈里&#xff0c;取出来栈…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...