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≤…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...