深入理解Java虚拟机(类加载器)

news2024/11/28 0:33:49

文章收录在网站:http://hardyfish.top/

文章收录在网站:http://hardyfish.top/

文章收录在网站:http://hardyfish.top/

文章收录在网站:http://hardyfish.top/

在这里插入图片描述

类加载器

类加载器有什么作用呢?

对于任意的一个类,都必须由加载它的类加载器,这个类本身一起共同确立其在JVM中的唯一性

  • 每一个类加载器,都拥有一个独立的类名称空间

换种说话就是:比较两个类是否相等,只有在这两个类是由同一个类加载器加载的前提下才有意义

  • 否则,即使这两个类来源于同一个Class文件,被同一个JVM加载
    • 只要加载它们的类加载器不同,这两个类也不相等

【注】:这里所指的相等,包括代表类的Class对象的equals()方法、isAssignableFrom()方法、isInstance()方法的返回结果

  • 也包括了使用instanceof关键字做对象所属关系判定等各种情况

JVM中有几类类加载器呢?

其实从JVM的角度看,大致可以分为两类:

启动类加载器(Bootstrap ClassLoader):

  • JVM自身的一部分,由C++实现的
    • 只针对HotSpot虚拟机,JDK9以后也采用了类似的虚拟机与Java类互相配合来实现Bootstrap ClassLoader的方式
      • 所以HotSpot也有一个无法获取实例的代表Bootstrap ClassLoader的Java类存在

其他所有的类加载器:

  • 全部由Java实现,独立存在于VM外部,并全都继承自抽象类java.lang.ClassLoader

【注】:从Java开发人员的角度来看,类加载器分的更细致

  • 自JDK1.2以来,Java一直保持着三层类加载器,双亲委派的类加载器结构

类加载器双亲委派模型(Parents Delegation Model)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

启动类加载器(Bootstrap ClassLoader):

也叫引导类加载器,负责加载(存放在<JAVA_HOME>\lib目录,或者被Xbootclasspath参数所指定的路径中存放的

  • 而且是JVM能够识别(按文件名识别,如rt.jar、tools.jar))的类库加载到JVM的内存中

启动类加载器无法被Java程序直接引用,用户在编写自定义类加载器时

  • 如果需要把加载请求委派给引导类加载器去处理,那直接使用null代替即可

扩展类加载器(Extension Class Loader):

  • 在类sun.misc.Launcher$ExtClassLoader中以Java代码的形式实现的

它负责加载<JAVA_HOME>\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有的类库

通过名字我们可以推断出,JVM开发团队允许用户将自己的类库放置在<JAVA_HOME>\lib\ext目录中

  • 以扩展Java SE的功能。因为是由Java语言实现的,所以我们可以直接在程序中使用该类加载器加载Class文件

【注】:在JDK9以后其实扩展机制已经可以被模块化代替了,因为模块化有天然的扩展能力

应用程序类加载器(Application Class Loader):

sun.misc.Launcher$AppClassLoader来实现

  • 该类加载器是ClassLoader类中的getSystem-ClassLoader()方法的返回值,所以我们也称其为系统类加载器

它负责加载用户类路径(ClassPath)上所有的类库,开发者同样可以直接在代码中使用这个类加载器

【注】:如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器

自定义类加载器(User Class Loader):

JDK 9之前的Java应用都是由这三种类加载器互相配合来完成加载的

当然我们也可以加入自定义的类加载器进扩展,比如:

  • 增加存储于磁盘之外的Class文件来源;

  • 实现类的隔离、重载等功能;

双亲委派模型的要求是什么?

顶层必须是启动类加载器

其余的类加载器都有自己的父类加载器;注意它们之间不是继承关系,而是通常使用组合(Composition)关系来复用父加载器的代码

双亲委派模型"的工作过程:

如果一个类加载器收到了类加载的请求,它首先会把这个请求委派给父类加载器去完成,每一层次的类加载器都是如此

因此所有的加载请求最终都应该传送到最顶层的启动类加载器中

  • 只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

双亲委派模型的好处:

Java中的类随着它的类加载器一起具备了一种带有优先级的层次关系

例如类java.lang.Object,它存放在rt.jar之中

无论哪一个类加载器要加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都能够保证是同一个类

反之如果没有该模型,那么不同的类加载器可能会加载同一个名为java.lang.Object的类

那么 在程序的classPath上就会有不同的Object类,那么我就不能保障Java类型体系了

双亲委派模型的核心代码: (全部集中在java.lang.ClassLoader的loadClass()方法之中)

protected synchronized Class<?> loadClass(String name, boolean resolve) throwsClassNotFoundException
{
	// 首先,检查请求的类是否已经被加载过了
	Class c = findLoadedClass(name);
	if (c == null) {  //如果未加载过就交给父类加载器
		try {
			if (parent != null) {
			c = parent.loadClass(name, false);
			} else {
				c = findBootstrapClassOrNull(name);
			}
		} catch (ClassNotFoundException e) {
		// 如果父类加载器抛出ClassNotFoundException,说明父类加载器无法完成加载请求
		}
		if (c == null) {
			// 在父类加载器无法加载时,再调用本身的findClass方法来进行类加载
			c = findClass(name);
		}
	}
	if (resolve) {
		resolveClass(c);
	}
	return c;
}

逻辑解析:

  • 检查请求加载的类是否已经被加载过

  • 如果没有则调用父加载器的loadClass()方法

  • 如果父加载器为空,则默认使用启动类加载器为父加载器

  • 如果父加载器失败,抛出ClassNotFoundException异常后,再调用自己的findClass()方法尝试进行加载

破坏双亲委派模型模型(一共三次):

第一次破坏:

因为JDK1.2以后双亲委派模型才被引入

但是在这之前类加载器的概念以及java.lang.ClassLoader就已经存在

  • 所以面对当时已经存在的自定义类加载器,我们为了兼容它们,无法避免ClassLoader被子类覆盖的可能性

因此我们想到一个解决方法,就是在java.lang.ClassLoader中添加一个新的protected方法findClass()

  • 并引导用户编写的类加载逻辑时尽可能去重写这个方法,而不是在loadClass()中编写代码

(在双亲委派模型的核心代码中的第④步,这样就做到了妥协,如果父加载器加载失败,则会调用自己的findClass()方法

  • 既按照用户意愿去加载类, 又保证符合双亲委派模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第二次破坏:

由自身缺陷导致,我们回想一下该模型的好处,无论哪一个类加载器要加载一个类,最终都是委派给处于模型最顶端的启动类加载器进行加载

如果该类加载加载失败,则抛出异常转而让下一层加载器加载(越基础的类由越上层的加载器进行加载)),这样解决了基础类型的不一致问题

但是有一个问题:

  • 如果基础类型(被启动类加载器加载的)要调用用户的代码,那怎么办?

针对这个问题,我们引入了线程上下文类加载器(Thread Context ClassLoader)

该加载器可以通过java.lang.Thread类的setContext-ClassLoader()方法进行设置

如果在创建线程的时候还没有创建,我们就通过它的父线程继承一个

  • 如果其父线程甚至整个程序都没有设锅置,那我们就将应用类加载器充当线程上下文类加载器

而这种行为是父类加载器请求子类加载器去完成类加载,也就是变相的打破了双亲委派模型的层次结构逆向使用类加载器

  • 已经违背了双亲委派模型的一般性原则

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第三次破坏:

用户对程序动态性的追求而导致的。动态性指的是一些很热的名词,比如代码热替换(Hot Swap)、模块热部署(Hot Deployment)等

比如IBM公司的OSGi,实现模块化热部署的关键是它自定义的类加载器机制的实现,每一个程序模块(OSGi中称为Bundle)都有一个自己的类加载器

当需要更换一个Bundle时,就把Bundle连同类加载器一起换掉以实现代码的热替换

在OSGi环境下,类加载器不再双亲委派模型推荐的树状结构,而是进一步发展为更加复杂的网状结构

它的查找顺序只有在开头符合双亲委派模型的原则,其余的类查找都是在平级的类加载器中进行

OSGI在运行期动态热部署上的优势是JDK9以后Sun/Oracle公司所提出Jigsaw不能的

  • 其只能局限于静态地解决模块间封装隔离和访问控制的问题

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

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

相关文章

基于一阶高斯低通滤波器的软件设计

前言 一阶RC低通滤波器&#xff08;巴特沃斯滤波&#xff09;-CSDN博客 一阶高斯低通滤波器不是一个直接的概念&#xff08;因为一阶滤波器通常不产生高斯型频率响应&#xff09;&#xff0c;这里我用软件的方式来模拟高斯低通滤波器的效果。 有纰漏请指出&#xff0c;转载…

C++竞赛初阶L1-13-第五单元-循环嵌套(29~30课)538: T456457 第 n 小的质数

题目内容 输入一个正整数 n&#xff0c;求正整数范围中第 n 小的质数。 输入格式 一个不超过 30000 的正整数 n。 输出格式 第 n 小的质数。 样例 1 输入 10 全部程序代码&#xff1a; #include<bits/stdc.h> using namespace std; int main() {long long n,i;ci…

【数据分享】《中国社会统计年鉴》(2006-2023)

而今天要限时免费分享的数据就是2006-2023年间出版的《中国社会统计年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 一、《中国社会统计年鉴》是一部反映我国社会发展相关领域基本情况的综合性统计资料年刊。书中收录了年全国和…

Leetcode每日刷题之1004.最大连续1的个数|||(C++)

1.题目解析 本题的目的是找出能最多翻转k个0的情况下最长连续的1的个数&#xff0c;并且这是一个二进制数组&#xff0c;只存在0和1&#xff0c;翻转0就是将0变为1 2.算法原理 首先我们想到的一定是暴力枚举&#xff0c;即依次列举出在最多翻转k个0的情况下所有连续1的子数组的…

类和对象(下)(2)

类和对象&#xff08;下&#xff09;(2) static成员 • ⽤static修饰的成员变量&#xff0c;称之为静态成员变量&#xff0c;静态成员变量⼀定要在类外进⾏初始化。 • 静态成员变量为当前类的所有对象所共享&#xff0c;不属于某个具体的对象&#xff0c;不存在对象中&#…

m4a转wav,使用FFmpeg和Python将M4A文件转换为WAV

你可以使用Python程序或Linux命令来将M4A文件转换为WAV文件。下面分别介绍这两种方法。 方法一:使用FFmpeg命令行工具(Linux命令) FFmpeg 是一个强大的多媒体处理工具,支持音视频转换、处理等操作。你可以在终端中使用以下命令将M4A文件转换为WAV文件: ffmpeg -i input…

网络通信(1)

网络&#xff1a; 不同主机间的通信问题 实现网络通信 物理层面 有一个 信息通路 &#xff08;有线 &#xff1b;无线 &#xff1b;5G&#xff1b;4G&#xff1b;星链 &#xff09;软件层面(逻辑层面) 也需要 一个通路 网络编程 Open System Interconnect (OSI网…

[OC]萝卜圈玩行车记录仪

图1-1&#xff0c;你的手动小车 代码是 #机器人驱动主程序 #请在main中编写您自己的机器人驱动代码 import tkinter as tk import turtle v0 # 速度 accFalse;slowFalse;leftFalse;rightFalse # 按键状态 step0.5 # 一次速度变化量 def keyup_press(event):global acc;accTru…

归并排序(Java实现)

目录 归并排序的思想 代码实现 思路 代码 归并排序的特点 归并排序的思想 归并排序的核心思想是分治&#xff0c;分而治之&#xff0c;就是把数组先分成若干个子数组&#xff0c;先将这些子数组排序后&#xff0c;再合并到一起去。 我们常说的归并排序是二路归并排序&…

uview-plus upload组件在上传视频在小程序环境下点击无反应

你们好&#xff0c;我是金金金。 场景 我正在使用uniapp开发微信小程序&#xff0c;使用的vue3&#xff0c;所以集成的uview-plus这个ui库 代码非常的简单&#xff0c;就是一个上传组件 在h5环境下点击是可以上传视频的&#xff0c;在微信小程序开发者工具里面点击完全没反应…

初阶数据结构之计数排序

非比较排序 计数排序 计数排序⼜称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应⽤。 操作步骤&#xff1a; 1&#xff09;统计相同元素出现次数 2&#xff09;根据统计的结果将序列回收到原来的序列中 #include "CountSort.h" void Count(int* arr, int n)…

利用GBDT进行对表格类数据的机器学习的实战项目

一&#xff1a;题目简介 在数据集中&#xff0c;每个样本都对应一个葡萄牙大学的学生。原始数据集中共有4424名学生&#xff0c;。对于每个学生&#xff0c;我们获得了人口统计数据、宏观经济数据以及课程前两个学期的表现。目标是预测学生在三年或四年学习后的状态&#xff1…

虚拟机桥接模式下设置静态IP

虚拟机桥接模式下设置静态ip 1. 设置虚拟机网络适配器为桥接模式2. 配置 CentOS 虚拟机的静态 IP3. 重启网络服务4. 验证配置5. 网络测试 要将 CentOS 虚拟机的网络模式从 NAT 模式更改为桥接模式&#xff0c;并设置静态 IP 地址以与 Windows 内网保持在相同网段&#xff0c;你…

PPP简介

介绍PPP特性的定义和目的。 定义 PPP&#xff08;Point-to-Point Protocol&#xff09;协议是一种点到点链路层协议&#xff0c;主要用于在全双工的同异步链路上进行点到点的数据传输。 目的 PPP协议是在串行线IP协议SLIP&#xff08;Serial Line Internet Protocol&#x…

vue---echarts环形图

1、完整代码直接可以cv <template><div id"main1"></div> </template><script> import * as echarts from echarts; // import { mapState } from vuex; // import { Alarm_Device } from ../utils/api.js; export default {name: P…

视频美颜SDK与直播美颜工具的架构设计与性能优化

本篇文章&#xff0c;小编将深入讲解视频美颜SDK与直播美颜工具的架构设计&#xff0c;并分享一些性能优化的实践经验。 一、视频美颜SDK的架构设计 视频美颜SDK的核心在于其模块化的设计思路。通常&#xff0c;视频美颜SDK由以下几个主要模块组成&#xff1a; 1.图像预处理…

【Qt】常用控件QCalendarWidget的使用

常用控件QCalendarWidget的使用 QCalendarWidget表示一个日历 核心属性 属性说明 selectDate 当前选中的⽇期 minimumDate 最⼩⽇期 maximumDate 最⼤⽇期 firstDayOfWeek 每周的第⼀天(也就是⽇历的第⼀列) 是周⼏. gridVisible 是否显⽰表格的边框 selectionMode…

AWS不同类型的EC2实例分别适合哪些场景?

Amazon Web Services&#xff08;AWS&#xff09;的弹性计算云&#xff08;EC2&#xff09;提供了多种实例类型&#xff0c;以满足不同的应用需求和工作负载。了解不同类型的 EC2 实例及其适用场景&#xff0c;可以帮助用户更好地优化性能和控制成本。九河云和大家一起了解一下…

Selenium + Python 自动化测试21(PO+HTML+Mail)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了PO模式并举例说明了基本的思路&#xff0c;今天我们继续学习。 本篇文章我们综合一下之前学习的内容&#xff0c;如先将PO模式和我们生成HTML报告融合起来&am…

gewe微信聊天机器人搭建教程

由于自身在机器人方面滚爬多年&#xff0c;现在收藏几个宝藏机器人 推荐一下自己常用的机器人&#xff1a; 适合有技术开发的公司&#xff0c;可以自主开发所需要的功能&#xff01;十分齐全 测试问文档&#xff1a;开发前必读 - GeWe开放平台 有需要的兄弟可以看一下&…