JVM系列-4.类加载器

news2024/11/25 4:35:09
  • 👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家
  • 📕系列专栏:Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术、JVM原理
  • 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
  • 🍂博主正在努力完成2023计划中:源码溯源,一探究竟
  • 📝联系方式:nhs19990716,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬👀

文章目录

  • 类加载器
    • 类加载器的分类
      • Arthas中类加载器相关的功能
      • 启动类加载器
      • Java中的默认类加载器
      • 扩展类加载器
      • 应用程序类加载器
      • Arthas中类加载器相关的功能
    • 双亲委派机制
    • 打破双亲委派机制
      • 打破双亲委派机制–自定义类加载器
      • 打破双亲委派机制的第二种方法:JDBC案例
      • 打破双亲委派机制的第三种方法: OSGi模块化
        • 使用阿里arthas不停机解决线上问题
    • JDK9之后的类加载器

类加载器

类加载器(ClassLoader)是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。
类加载器只参与加载过程中的字节码获取并加载到内存这一部分。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

类加载器的分类

类加载器分为两类,一类是Java代码中实现的,一类是Java虚拟机底层源码实现的。

在这里插入图片描述

类加载器的设计JDK8和8之后的版本差别较大,JDK8及之前的版本中默认的类加载器有如下几种:

在这里插入图片描述

Arthas中类加载器相关的功能

类加载器的详细信息可以通过classloader命令查看:

classloader - 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource

在这里插入图片描述

启动类加载器

在这里插入图片描述

其中最核心的就是rt.jar是jdk8中最核心的jar包,平时用到的字符串String类,装箱类型Integer,还有日期类Date等等。启动类加载器将这些都加载进来之后,相当于提供了一个基础的运行环境。

ClassLoader classLoader = String.class.getClassLoader();
System.out.println(classLoader);

输出为null

但是由于这个类加载器不存在于java代码中,而是位于虚拟机环境中,所以在java环境中获取不到。所以出于安全性的考虑,在代码中,不允许我们获取到虚拟机的启动类。

制作jar的方式,idea maven install

Java中的默认类加载器

扩展类加载器和应用程序类加载器都是JDK中提供的、使用Java编写的类加载器。

它们的源码都位于sun.misc.Launcher中,是一个静态内部类。继承自URLClassLoader。具备通过目录或者指定jar包将字节码文件加载到内存中。

在这里插入图片描述

扩展类加载器

在这里插入图片描述

应用程序类加载器

在这里插入图片描述

Arthas中类加载器相关的功能

类加载器的加载路径可以通过classloader –c hash值 查看:

在这里插入图片描述

双亲委派机制

由于java虚拟机中有多个类加载器,双亲委派机制的核心就是解决一个类到底是由谁加载的问题。

在这里插入图片描述

在这里插入图片描述

在Java中如何使用代码的方式去主动加载一个类呢?

方式1:使用Class.forName方法,使用当前类的类加载器去加载指定的类。

方式2:获取到类加载器,通过类加载器的loadClass方法指定某个类加载器加载。

在Idea中测试下面的案例:

在这里插入图片描述

应用程序类加载器的parent父类加载器是扩展类加载器,而扩展类加载器的parent是空。

启动类加载器使用C++编写,没有上级类加载器。

在这里插入图片描述

类加载器的继承关系可以通过classloader –t 查看:

在这里插入图片描述

如果类加载的parent为null,则会提交给启动类加载器处理。

在这里插入图片描述

如果所有的父类加载器都无法加载该类,则由当前类加载器自己尝试加载。所以看上去是自顶向下尝试加载。

在这里插入图片描述

第二次再去加载相同的类,仍然会向上进行委派,如果某个类加载器加载过就会直接返回。

在这里插入图片描述

双亲委派机制指的是:自底向上查找是否加载过,再由顶向下进行加载。

在这里插入图片描述

另一个案例:com.itheima.my.C这个类在当前程序的classpath中,看看是如何加载的。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

打破双亲委派机制

在这里插入图片描述

打破双亲委派机制–自定义类加载器

一个Tomcat程序中是可以运行多个Web应用的,如果这两个应用中出现了相同限定名的类,比如Servlet类,Tomcat要保证这两个类都能加载并且它们应该是不同的类。

如果不打破双亲委派机制,当应用类加载器加载Web应用1中的MyServlet之后,Web应用2中相同限定名的MyServlet类就无法被加载了。

在这里插入图片描述

Tomcat使用了自定义类加载器来实现应用之间类的隔离。

每一个应用会有一个独立的类加载器加载对应的类。

在这里插入图片描述

先来分析ClassLoader的原理,ClassLoader中包含了4个核心方法。

双亲委派机制的核心代码就位于loadClass方法中。

在这里插入图片描述

阅读双亲委派机制的核心代码,分析如何通过自定义的类加载器打破双亲委派机制。

打破双亲委派机制的核心就是将下边这一段代码重新实现。

//parent等于null说明父类加载器是启动类加载器,直接调用findBootstrapClassOrNull
//否则调用父类加载器的加载方法
if (parent != null) {
 	c = parent.loadClass(name, false);
 	} else {
 		c = findBootstrapClassOrNull(name);
 	}
//父类加载器爱莫能助,我来加载!
if (c == null) 
 	c = findClass(name);

自定义类加载器父类怎么是AppClassLoader呢?

在这里插入图片描述

以Jdk8为例,ClassLoader类中提供了构造方法设置parent的内容:

在这里插入图片描述

这个构造方法由另外一个构造方法调用,其中父类加载器由getSystemClassLoader方法设置,该方法返回的是AppClassLoader。

在这里插入图片描述

两个自定义类加载器加载相同限定名的类,不会冲突吗?

不会冲突,在同一个Java虚拟机中,只有相同类加载器+相同的类限定名
会被认为是同一个类。

在Arthas中使用sc –d 类名的方式查看具体的情况。

在这里插入图片描述

正确的去实现一个自定义类加载器的方式是重写findClass方法,这样不会破坏双亲委派机制。

在这里插入图片描述

打破双亲委派机制的第二种方法:JDBC案例

JDBC中使用了DriverManager来管理项目中引入的不同数据库的驱动,比如mysql驱动、oracle驱动。

在这里插入图片描述

DriverManager类位于rt.jar包中,由启动类加载器加载。

在这里插入图片描述

依赖中的mysql驱动对应的类,由应用程序类加载器来加载。

在这里插入图片描述

DriverManager属于rt.jar是启动类加载器加载的。而用户jar包中的驱动需要由应用类加载器加载,这就违反了双亲委派机制。

在这里插入图片描述

DriverManager怎么知道jar包中要加载的驱动在哪儿?

在这里插入图片描述

DriverManage使用SPI机制,最终加载jar包中对应的驱动类。

在这里插入图片描述

SPI全称为(Service Provider Interface) 是JDK内置的一种服务提供发现机制

其工作原理:

1.在ClassPath路径下的META-INF/services文件夹下,以接口的全限定名来命名文件名,对应的文件里面写该接口的实现。

2.使用ServiceLoader加载实现类

在这里插入图片描述

SPI中是如何获取到应用程序类加载器的?

SPI中使用了线程上下文中保存的类加载器进行类的加载,这个类加载器一般是应用程序类加载器。

在这里插入图片描述

1、启动类加载器加载DriverManager。

2、在初始化DriverManager时,通过SPI机制加载jar包中的myql驱动。

3、SPI中利用了线程上下文类加载器(应用程序类加载器)去加载类并创建对象。

这种由启动类加载器加载的类,委派应用程序类加载器去加载类的方式,打破了双亲委派机制。

在这里插入图片描述

打破双亲委派机制的第三种方法: OSGi模块化

历史上,OSGi模块化框架。它存在同级之间的类加载器的委托加载。OSGi还使用类加载器实现了热部署的功能。

热部署指的是在服务不停止的情况下,动态地更新字节码文件到内存中。

在这里插入图片描述

使用阿里arthas不停机解决线上问题

小李的团队将代码上线之后,发现存在一个小bug,但是用户急着使用,如果重
新打包再发布需要一个多小时的时间,所以希望能使用arthas尽快的将这个问
题修复。

思路:

  • 在出问题的服务器上部署一个 arthas,并启动。
  • jad --source-only 类全限定名 > 目录/文件名.java
    jad 命令反编译,然后可以用其它编译器,比如 vim 来修改源码
  • sc -d 输入类名,找到hashcode
  • mc –c 类加载器的hashcode 目录/文件名.java -d 输出目录
    mc 命令用来编译修改过的代码
  • retransform class文件所在目录/xxx.class
    用 retransform 命令加载新的字节码

注意事项:

1、程序重启之后,字节码文件会恢复,除非将class文件放入jar包中进行更新。
2、使用retransform不能添加方法或者字段,也不能更新正在执行中的方法。

JDK9之后的类加载器

JDK8及之前的版本中,扩展类加载器和应用程序类加载器的源码位于rt.jar包中的sun.misc.Launcher.java。

在这里插入图片描述

由于JDK9引入了module的概念,类加载器在设计上发生了很多变化。

在这里插入图片描述

启动类加载器使用Java编写,位于jdk.internal.loader.ClassLoaders类中。

Java中的BootClassLoader继承自BuiltinClassLoader实现从模块中找到要加载的字节码资源文件。

启动类加载器依然无法通过java代码获取到,返回的仍然是null,保持了统一。

在这里插入图片描述

扩展类加载器被替换成了平台类加载器(Platform Class Loader)。

(img-hsgsO33k-1705921789406)]

启动类加载器使用Java编写,位于jdk.internal.loader.ClassLoaders类中。

Java中的BootClassLoader继承自BuiltinClassLoader实现从模块中找到要加载的字节码资源文件。

启动类加载器依然无法通过java代码获取到,返回的仍然是null,保持了统一。

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

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

相关文章

java数据结构与算法刷题-----LeetCode645. 错误的集合(位运算解法需要重点掌握)

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 法一:桶排序思想法二:位运算 法一&#x…

imu_utils安装及标定教程

本文使用香港科技大学的imu_utils方差工具标定,首先将INDEMIND双目惯性模组静止放置三个小时。然后采集IMU数据,生成Allan方差数据,由图分析得到加速度和角速度的高斯白噪声和随机游走Bias误差。 系统配置 系统版本ubuntu18.04OpenCV3.4.13…

C/C++读写文件和stringstream类

目录 C处理文件打开文件两种函数的区别 读文件两种函数区别其它读操作的函数fgetc:从文件中读取一个字符fgets:从文件中读取一个字符串fscanf:按格式从文件中读取指定内容,与scanf函数类似 写文件其它的常用写操作函数fputc&#…

【LeetCode-135】分发糖果(贪心)

LeetCode135.分发糖果 题目描述 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果。…

js中找出两个数组中不同的元素

文章目录 一、题目二、方法2.1、方法一2.2、方法二2.3、方法三 三、最后 一、题目 两个数组 var A [1, 5, 6]; var B [2, 6, 7],实现一个方法,找出仅存在于A 或者仅存在于B中的所有数字 二、方法 2.1、方法一 const filterArr (arr1, arr2) > …

5大免费代理IP合集,你的代理IP该换啦!

一连代理 代理IP提供平台,代理IP覆盖HTTP/HTTPS/SOCKS5协议,涵盖直连和隧道代理。一键操作可以随机更换IP,实现高效稳定的网络代理。支持在PC、iOS和安卓等平台上使用。当前免费试用选项,让用户能够在使用之前先了解服务的性能和效…

归并排序模板

模板在文末,以下步骤方便理解记忆。 先贴一张快速排序模板步骤,用于对比记忆 归并排序步骤: (0)如果数组左边界L ≥ 数组右边界,则不需要排序,直接return。 (1)直接取…

力扣第92题——反转链表 II(C语言题解)

题目描述 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#xff1…

成绩等级分数段查询(python条件分支语句match...case...)

根据有效分数序列及等级差值&#xff0c;计算并打印等级相应分数区间。 (笔记模板由python脚本于2024年01月20日 23:57:32创建&#xff0c;本篇笔记适合会条件分支语句的初学者的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&…

python:socket基础操作(2)-《udp发送信息》

基础发送udp信息 1.导入socket模块 2.使用udp模块 3.发送内容 4.关闭套接字 很简单的4步就可以实现udp的消息发送 import socket # 导入模块udp_socket socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 使用ipv4 udp协议udp_socket.sendto(b"hello world",(&…

翻毛皮鞋脏了不会清洗怎么办?资深劳保鞋厂家来教你

劳保鞋皮面材质中除了常见的牛皮材质&#xff0c;翻毛皮也是频繁使用的材料&#xff0c;材质不同&#xff0c;在养护上也有区别&#xff0c;今天百华小编来和大家聊聊翻毛皮材质的鞋子清洁方法。 翻毛皮鞋清洗前的准备工作 1.除灰&#xff1a;对于表面灰尘&#xff0c;可以使用…

C语言第六弹---分支语句(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 分支语句 1、 逻辑操作符&#xff1a;&& , || , &#xff01;4.1、 逻辑取反运算符 &#xff01;4.2、 与运算符4.3、 或运算符4.4、 练习&#xff1a;闰…

磁悬浮人工心脏的不良事件分析:美国FDA数据库的启示

引言&#xff1a; 左心室辅助装置&#xff08;LVAD&#xff09;是治疗末期难治性心力衰竭&#xff08;HF&#xff09;患者的有效手段。磁悬浮人工心脏HeartMate-3&#xff08;磁悬浮人工心脏&#xff09;作为第三代LVAD&#xff0c;自2017年获得美国食品药品监督管理局&#x…

pygame入门学习(四)位图的使用

大家好&#xff01;我是码银&#x1f970; 欢迎关注&#x1f970;&#xff1a; CSDN&#xff1a;码银 公众号&#xff1a;码银学编程 载入图片 pygame.image.load( )&#xff0c;Pygame 可以通过pygame.image.load( )函数处理位图文件。 大致可以支持以下文件&#xff1a;JPG…

怎么给wordpress网站底部页脚添加备案号和链接?

以前“WordPress后台 >> 常规”最底部是有一个ICP备案号的&#xff0c;我们只需要填写备案号并保存更改即可让WordPress自带主题底部显示ICP备案号&#xff0c;但是现在新版本的WordPress已经没有了这个ICP备案号选项&#xff0c;而且也无法直接添加公安联网备案号&#…

前端基于XLSX实现数据导出到Excel表格,以及提示“文件已经被损坏,无法打开”的解决方法

文章目录 一、vue实现导出excel1、前端实现1、安装xlsx依赖2、引入3、方法4、使用4.1、将一个二维数组转成sheet4.2、将一个对象数组转成sheet4.3、合并单元格4.4、一次导出多个sheet 5、支持的文件格式 2、后端实现 二、导出文件损坏1、前端请求导出接口&#xff0c;增加返回类…

对称二叉树,力扣

题目地址&#xff1a; 101. 对称二叉树 - 力扣&#xff08;LeetCode&#xff09; 难度&#xff1a;简单 今天刷对称二叉树&#xff0c;大家有兴趣可以点上面链接&#xff0c;看看题目要求&#xff0c;试着做一下。 题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c;…

区块链社交:Facebook在去中心化时代的探索

随着区块链技术的崛起&#xff0c;数字社交领域也正迎来一场革命。Facebook&#xff0c;作为全球最大的社交媒体平台之一&#xff0c;不甘落后&#xff0c;积极探索区块链的应用前景。本文将深入探讨Facebook在去中心化时代对区块链社交的探索&#xff0c;以及这一探索可能引发…

控制项目进展

优质博文 IT-BLOG-CN 假如一个项目准备工作做的非常周详&#xff0c;现在要做的就是监督项目的进展情况&#xff0c;理想状况下事情应当进展的很顺利&#xff0c;但实际上我们会发现项目永远不会完全按照经计划执行&#xff0c;我们必须进行项目控制。也就是我们需要不断进行调…

基于springboot+vue的在线文档管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 背景和意…