ClassLoader源码
介绍
ClassLoader 顾名思义就是类加载器 ClassLoader 是一个抽象类 没有父类
作用
1.负责将 Class 加载到 JVM 中
2.审查每个类由谁加载(父优先的等级加载机制)
3.将 Class 字节码重新解析成 JVM 统一要求的对象格式
常量&变量
//注册本地方法private static native void registerNatives();static {registerNatives();}// The parent class loader for delegation// Note: VM hardcoded the offset of this field, thus all new fields// must be added *after* it.//父类加载器,需要与BuiltinClassLoader中的parent区分private final ClassLoader parent;// Maps class name to the corresponding lock object when the current// class loader is parallel capable.// Note: VM also uses this field to decide if the current class loader// is parallel capable and the appropriate lock object for class loading.//当前类加载器具有并行功能时,将其下的类名映射到锁对象private final ConcurrentHashMap<String, Object> parallelLockMap;// Hashtable that maps packages to certs// 将包名映射到身份证书private final Map <String, Certificate[]> package2certs;// Shared among all packages with unsigned classesprivate static final Certificate[] nocerts = new Certificate[0];// The classes loaded by this class loader. The only purpose of this table// is to keep the classes from being GC'ed until the loader is GC'ed.// 记录当前类加载器加载的类private final Vector<Class<?>> classes = new Vector<>();// The "default" domain. Set as the default ProtectionDomain on newly// created classes.private final ProtectionDomain defaultDomain =new ProtectionDomain(new CodeSource(null, (Certificate[]) null),null, this, null);// The packages defined in this class loader. Each package name is mapped// to its corresponding Package object.// @GuardedBy("itself")// 记录当前类加载器定义的包private final HashMap<String, Package> packages = new HashMap<>();// The class loader for the system// @GuardedBy("ClassLoader.class")//system class loader,可能是内置的AppClassLoader(默认),也可能是自定义的类加载器private static ClassLoader scl;// Set to true once the system class loader has been set// @GuardedBy("ClassLoader.class")private static boolean sclSet;// All native library names we've loaded.private static Vector<String> loadedLibraryNames = new Vector<>();// Native libraries belonging to system classes.private static Vector<NativeLibrary> systemNativeLibraries= new Vector<>();// Native libraries associated with the class loader.private Vector<NativeLibrary> nativeLibraries = new Vector<>();// native libraries being loaded/unloaded.private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>();// The paths searched for librariesprivate static String usr_paths[];private static String sys_paths[];final Object assertionLock;// The default toggle for assertion checking.// @GuardedBy("assertionLock")private boolean defaultAssertionStatus = false;// Maps String packageName to Boolean package default assertion status Note// that the default package is placed under a null map key. If this field// is null then we are delegating assertion status queries to the VM, i.e.,// none of this ClassLoader's assertion status modification methods have// been invoked.// @GuardedBy("assertionLock")private Map<String, Boolean> packageAssertionStatus = null;// Maps String fullyQualifiedClassName to Boolean assertionStatus If this// field is null then we are delegating assertion status queries to the VM,// i.e., none of this ClassLoader's assertion status modification methods// have been invoked.// @GuardedBy("assertionLock")Map<String, Boolean> classAssertionStatus = null;
构造方法
private ClassLoader(Void unused, ClassLoader parent) {this.parent = parent;//类加载器是否可并行if (ParallelLoaders.isRegistered(this.getClass())) {parallelLockMap = new ConcurrentHashMap<>();package2certs = new ConcurrentHashMap<>();assertionLock = new Object();} else {// no finer-grained lock; lock on the classloader instanceparallelLockMap = null;package2certs = new Hashtable<>();assertionLock = this;}}/*** Creates a new class loader using the specified parent class loader for* delegation.** <p> If there is a security manager, its {@link* SecurityManager#checkCreateClassLoader()* <tt>checkCreateClassLoader</tt>} method is invoked. This may result in* a security exception. </p>** @param parent* The parent class loader** @throws SecurityException* If a security manager exists and its* <tt>checkCreateClassLoader</tt> method doesn't allow creation* of a new class loader.** @since 1.2*/protected ClassLoader(ClassLoader parent) {this(checkCreateClassLoader(), parent);}/*** Creates a new class loader using the <tt>ClassLoader</tt> returned by* the method {@link #getSystemClassLoader()* <tt>getSystemClassLoader()</tt>} as the parent class loader.** <p> If there is a security manager, its {@link* SecurityManager#checkCreateClassLoader()* <tt>checkCreateClassLoader</tt>} method is invoked. This may result in* a security exception. </p>** @throws SecurityException* If a security manager exists and its* <tt>checkCreateClassLoader</tt> method doesn't allow creation* of a new class loader.*/protected ClassLoader() {this(checkCreateClassLoader(), getSystemClassLoader());}
常用方法
loadClass
/*** Loads the class with the specified <a href="#name">binary name</a>.* This method searches for classes in the same manner as the {@link* #loadClass(String, boolean)} method. It is invoked by the Java virtual* machine to resolve class references. Invoking this method is equivalent* to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,* false)</tt>}.** @param name* The <a href="#name">binary name</a> of the class** @return The resulting <tt>Class</tt> object** @throws ClassNotFoundException* If the class was not found* 加载指定二进制名称的类*/public Class<?> loadClass(String name) throws ClassNotFoundException {return loadClass(name, false);}/*** Loads the class with the specified <a href="#name">binary name</a>. The* default implementation of this method searches for classes in the* following order:** <ol>** <li><p> Invoke {@link #findLoadedClass(String)} to check if the class* has already been loaded. </p></li>** <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method* on the parent class loader. If the parent is <tt>null</tt> the class* loader built-in to the virtual machine is used, instead. </p></li>** <li><p> Invoke the {@link #findClass(String)} method to find the* class. </p></li>** </ol>** <p> If the class was found using the above steps, and the* <tt>resolve</tt> flag is true, this method will then invoke the {@link* #resolveClass(Class)} method on the resulting <tt>Class</tt> object.** <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link* #findClass(String)}, rather than this method. </p>** <p> Unless overridden, this method synchronizes on the result of* {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method* during the entire class loading process.** @param name* The <a href="#name">binary name</a> of the class** @param resolve* If <tt>true</tt> then resolve the class* 如果为true则解析该类* @return The resulting <tt>Class</tt> object** @throws ClassNotFoundException* If the class could not be found*/protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loaded//校验class是否被加载Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {//递归,调用父类加载器的loadClassc = parent.loadClass(name, false);} else {//调用启动类加载器(虚拟机提供的加载器,即为BootStrapClassLoader)c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();//父类加载器没有找到,再调用本身(这个本身包括ext和app)的findClass(name)来查找父类c = findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {//链接resolveClass(c);}return c;}}
getResource
/*** Finds the resource with the given name. A resource is some data* (images, audio, text, etc) that can be accessed by class code in a way* that is independent of the location of the code.** <p> The name of a resource is a '<tt>/</tt>'-separated path name that* identifies the resource.** <p> This method will first search the parent class loader for the* resource; if the parent is <tt>null</tt> the path of the class loader* built-in to the virtual machine is searched. That failing, this method* will invoke {@link #findResource(String)} to find the resource. </p>** @apiNote When overriding this method it is recommended that an* implementation ensures that any delegation is consistent with the {@link* #getResources(java.lang.String) getResources(String)} method.** @param name* The resource name** @return A <tt>URL</tt> object for reading the resource, or* <tt>null</tt> if the resource could not be found or the invoker* doesn't have adequate privileges to get the resource.** @since 1.1* 获得指定名称的资源 图像,音频,文本等*/public URL getResource(String name) {URL url;if (parent != null) {//搜索父类加载器的资源url = parent.getResource(name);} else {//不存在父类,搜索虚拟机默认的类加载器的路径,url = getBootstrapResource(name);}//仍然获取不到资源if (url == null) {//调用findResource(String)来查找资源url = findResource(name);}return url;}
双亲委派模型
提起Classs Loader 的类加载机制就不得不说说它的“双亲委派模型“
ClassLoader使用的是双亲委托模型来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是组合关系),虚拟机内置的启动类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。
可以发现委托是从下向上,然后具体查找过程却是自上至下。
-
最高一层是BootStrap Class Loader
它是在JVM 启动时候创建的,负载装载核心的Java 类, 比如Object , System String 等,主要位于jre/lib/rt.jar 中。
-
第二层是Platform ClassLoader
即平台类加载器,负责装载扩展系统类,比如XMl, 加密,压缩相关的功能类,主要位于jre/lib/ext/*.jar
-
第三层类是Application ClassLoader
即应用类加载器,主要加载用户自定义的ClassPath 路径下的类,主要位于ClassPath 中的jar.
相关文章:

ClassLoader源码
介绍 ClassLoader 顾名思义就是类加载器 ClassLoader 是一个抽象类 没有父类 作用 1.负责将 Class 加载到 JVM 中 2.审查每个类由谁加载(父优先的等级加载机制) 3.将 Class 字节码重新解析成 JVM 统一要求的对象格式 常量&变量 //注册本地方法…...

Kafka分区消息积压排查指南
针对某个TOPIC只有几个分区积压的场景,可以采用以下方法进行排查: 消息生产是否指定key? 如果指定了消息key,那么消息会指定生产到hash(key)的分区中。如果指定了key,那么有下列几种可能: 生产该key的消息体…...

数据库 期末复习(4) 概念数据库的设计
第一部分 为啥要引入概念数据库 感觉只有一个重点 实体联系模型----ER模型 第二部分-----实体联系模型 这个例子可以全看完之后再来看 举个例子:根据COMPANY数据库的需求来构造数据库模式:The company is organized into DEPARTMENTs. Each department has a name, number …...
WuThreat身份安全云-TVD每日漏洞情报-2023-05-26
漏洞名称:Barracuda Email Security Gateway TAR文件命令注入 漏洞级别:严重 漏洞编号:CVE-2023-2868,CNNVD-202305-2128 相关涉及:Barracuda Email Security Gateway 5.1.3.001 漏洞状态:在野 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-12949 漏洞名称…...

关于Idea的一些常用设置项
1. 输出中文不乱码 设置工程项目编码 file -> settings -> Editor -> File Encodings-> 如下图通通UTF-8 2. 创建文件自动设置本文模板 File–>settings–>Editor–>File and Code Templates–>Includes -> 输入类注释模板 /*** Classname ${N…...

Python使用WMI模块获取Windows系统的硬件信息,并使用pyinstaller库编译打包成exe的可执行文件
引言 今天给大家分享一篇有关Python和Windows系统的文章。你有没有想过如何获取Windows系统的硬件信息?或者你是否曾经尝试过将Python脚本编译打包成可执行文件?如果你对这些问题感兴趣,那么这篇文章一定适合你。 背景 由于公司现阶段大多…...
JavaScript语句(七)
JavaScript语句 1、条件语句2、循环语句3、break 和 continue 语句4、异常处理语句4.1、抛出异常4.2、捕获异常4.3、处理异步代码块中的异常4.3.1、Promise4.3.2、async/await try-catch 4.4、处理未捕获的异常4.5、总结 1、条件语句 名称描述if当指定条件为 true 时…...
孪生诱捕网络在欺骗防御领域的应用
信息化在给人们带来便利的同时,网络信息安全问题也日益凸显。尤其是随着网络攻击由传统的盲目、直接、粗暴的方式转变为目前的精确化、持久化、隐匿式的恶意攻击,攻击过程中只需发现并利用一个未被修复的漏洞或不安全配置即可击破边界防御,试图将攻击者拒之门外的安全防护方…...

【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路
前言 前面讲了Jmeter在性能测试中的应用及扩展。随着测试的深入,我们发现在性能测试中也会遇到不少的重复工作。 比如某新兴业务处于上升阶段,需要在每个版本中,对某些新增接口进行性能测试,有时还需要在一天中的不同时段分别进行…...

ARM体系结构与异常处理
目录 一、ARM体系架构 1、ARM公司概述 ARM的含义 ARM公司 2.ARM产品系列 3.指令、指令集 指令 指令集 ARM指令集 ARM指令集 Thumb指令集 (属于ARM指令集) 4.编译原理 5.ARM数据类型 字节序 大端对齐 小端对齐 …...
招聘网站—Hive数据分析
招聘网站—Hive数据分析 第1关:统计最热门的十种职业(招聘人数最多) #进入hive hive#在hive中创建数据库 mydb create database mydb;#使用数据库 mydb use mydb;#创建表 recruitcleaned 并使用"/t"分割字段 create table re…...
双指针滑动窗口整理1——长度最小的子数组、水果成篮
209. 长度最小的子数组 这篇文章主要是想针对这题 209. 长度最小的子数组,总结一下双指针或是滑动窗口的小细节。对于暴力算法,我们就不再阐释了。 算法原理: 滑动窗口主要是通过控制循环终止节点j,并移动i来缩放窗口。具体而言…...
textarea之换行、replace、\n、br、innerHTML
文章目录 前言换行符介绍JavaScript部分html部分 前言 textarea标签本身不识别换行功能,回车换行用的是\n换行符,输入时的确有换行的效果,但是渲染时就只是一个空格了。这时就需要利用换行符\n和br标签的转换进行处理。 换行符介绍 表格 序…...

SKD240
SKD240 系列智能电力仪表 SKD240 系列智能电力仪表是陕西斯科德智能科技有限公司自主研发、生产的。 产品概述 - 点击了解详情 SKD240采用先进的微处理器和数字信号处理技术(内置主芯片采用32位单片机, 采用32位浮点型真有效值处理数据),测量…...
大数据采集怎么做呢?
随着互联网的发展,大数据已经成为了一个非常热门的话题。大数据采集是大数据分析的第一步,也是非常重要的一步。本文将介绍大数据采集的基本概念、采集的方法、采集的难点以及采集的注意事项等方面,希望能够对大家有所帮助。 一、大数据采集…...

【学习日记】操作系统-入门知识-个人学习记录
我的学习笔记链接: MyLinuxProgramming 参考资料 CSAPP操作系统导论OSTEP √APUEhttps://stevens.netmeister.org/631软件调试王道-操作系统操作系统真象还原小林coding-图解系统https://xiaolincoding.com嵌入式软件开发笔试面试指南Linux是怎样工作的2020 南京大…...

ChatGPT自动生成思维导图
🍏🍐🍊🍑🍒🍓🫐🥑🍋🍉 ChatGPT自动生成思维导图 文章目录 🍐问题引入🍐具体操作markmapXmind 🐳结语 …...

count(0)、count(1)和count(*)、count(列名) 的区别
当我们对一张数据表中的记录进行统计的时候,习惯都会使用 count 函数来统计,但是 count 函数传入的参数有很多种,比如 count(1)、count(*)、count(字段) 等。 到底哪种效率是最好的呢?是不是 count(*) 效率最差? 一.…...

python爬虫入门,10分钟就够了,这可能是我见过最简单的基础教学
一、基础入门 1.1什么是爬虫 爬虫(spider,又网络爬虫),是指向网站/网络发起请求,获取资源后分析并提取有用数据的程序。 从技术层面来说就是 通过程序模拟浏览器请求站点的行为,把站点返回的HTML代码/JSON数据/二进制数据&…...
华为OD机试真题 Java 实现【记票统计】【牛客练习题】
一、题目描述 请实现一个计票统计系统。你会收到很多投票,其中有合法的也有不合法的,请统计每个候选人得票的数量以及不合法的票数。 (注:不合法的投票指的是投票的名字不存在n个候选人的名字中!!) 数据范围:每组输入中候选人数量满足 1≤n≤100 ,总票数量满足 1≤…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...