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

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

image-20230604054300171

    /*** 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实例对象。

image-20230604054245374

可以发现委托是从下向上,然后具体查找过程却是自上至下

  • 最高一层是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.审查每个类由谁加载&#xff08;父优先的等级加载机制&#xff09; 3.将 Class 字节码重新解析成 JVM 统一要求的对象格式 常量&变量 //注册本地方法…...

Kafka分区消息积压排查指南

针对某个TOPIC只有几个分区积压的场景&#xff0c;可以采用以下方法进行排查&#xff1a; 消息生产是否指定key&#xff1f; 如果指定了消息key&#xff0c;那么消息会指定生产到hash(key)的分区中。如果指定了key&#xff0c;那么有下列几种可能&#xff1a; 生产该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系统的硬件信息&#xff1f;或者你是否曾经尝试过将Python脚本编译打包成可执行文件&#xff1f;如果你对这些问题感兴趣&#xff0c;那么这篇文章一定适合你。 背景 由于公司现阶段大多…...

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 时&#xf…...

孪生诱捕网络在欺骗防御领域的应用

信息化在给人们带来便利的同时,网络信息安全问题也日益凸显。尤其是随着网络攻击由传统的盲目、直接、粗暴的方式转变为目前的精确化、持久化、隐匿式的恶意攻击,攻击过程中只需发现并利用一个未被修复的漏洞或不安全配置即可击破边界防御,试图将攻击者拒之门外的安全防护方…...

【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路

前言 前面讲了Jmeter在性能测试中的应用及扩展。随着测试的深入&#xff0c;我们发现在性能测试中也会遇到不少的重复工作。 比如某新兴业务处于上升阶段&#xff0c;需要在每个版本中&#xff0c;对某些新增接口进行性能测试&#xff0c;有时还需要在一天中的不同时段分别进行…...

ARM体系结构与异常处理

目录 一、ARM体系架构 1、ARM公司概述 ARM的含义 ARM公司 2.ARM产品系列 3.指令、指令集 指令 指令集 ARM指令集 ARM指令集 Thumb指令集 &#xff08;属于ARM指令集&#xff09; 4.编译原理 5.ARM数据类型 字节序 大端对齐 小端对齐 …...

招聘网站—Hive数据分析

招聘网站—Hive数据分析 第1关&#xff1a;统计最热门的十种职业&#xff08;招聘人数最多&#xff09; #进入hive hive#在hive中创建数据库 mydb create database mydb;#使用数据库 mydb use mydb;#创建表 recruitcleaned 并使用"/t"分割字段 create table re…...

双指针滑动窗口整理1——长度最小的子数组、水果成篮

209. 长度最小的子数组 这篇文章主要是想针对这题 209. 长度最小的子数组&#xff0c;总结一下双指针或是滑动窗口的小细节。对于暴力算法&#xff0c;我们就不再阐释了。 算法原理&#xff1a; 滑动窗口主要是通过控制循环终止节点j&#xff0c;并移动i来缩放窗口。具体而言…...

textarea之换行、replace、\n、br、innerHTML

文章目录 前言换行符介绍JavaScript部分html部分 前言 textarea标签本身不识别换行功能&#xff0c;回车换行用的是\n换行符&#xff0c;输入时的确有换行的效果&#xff0c;但是渲染时就只是一个空格了。这时就需要利用换行符\n和br标签的转换进行处理。 换行符介绍 表格 序…...

SKD240

SKD240 系列智能电力仪表 SKD240 系列智能电力仪表是陕西斯科德智能科技有限公司自主研发、生产的。 产品概述 - 点击了解详情 SKD240采用先进的微处理器和数字信号处理技术&#xff08;内置主芯片采用32位单片机, 采用32位浮点型真有效值处理数据&#xff09;&#xff0c;测量…...

大数据采集怎么做呢?

随着互联网的发展&#xff0c;大数据已经成为了一个非常热门的话题。大数据采集是大数据分析的第一步&#xff0c;也是非常重要的一步。本文将介绍大数据采集的基本概念、采集的方法、采集的难点以及采集的注意事项等方面&#xff0c;希望能够对大家有所帮助。 一、大数据采集…...

【学习日记】操作系统-入门知识-个人学习记录

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

ChatGPT自动生成思维导图

&#x1f34f;&#x1f350;&#x1f34a;&#x1f351;&#x1f352;&#x1f353;&#x1fad0;&#x1f951;&#x1f34b;&#x1f349; ChatGPT自动生成思维导图 文章目录 &#x1f350;问题引入&#x1f350;具体操作markmapXmind &#x1f433;结语 &#x1f…...

count(0)、count(1)和count(*)、count(列名) 的区别

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

python爬虫入门,10分钟就够了,这可能是我见过最简单的基础教学

一、基础入门 1.1什么是爬虫 爬虫(spider&#xff0c;又网络爬虫)&#xff0c;是指向网站/网络发起请求&#xff0c;获取资源后分析并提取有用数据的程序。 从技术层面来说就是 通过程序模拟浏览器请求站点的行为&#xff0c;把站点返回的HTML代码/JSON数据/二进制数据&…...

华为OD机试真题 Java 实现【记票统计】【牛客练习题】

一、题目描述 请实现一个计票统计系统。你会收到很多投票,其中有合法的也有不合法的,请统计每个候选人得票的数量以及不合法的票数。 (注:不合法的投票指的是投票的名字不存在n个候选人的名字中!!) 数据范围:每组输入中候选人数量满足 1≤n≤100 ,总票数量满足 1≤…...

嵌入式轻量级参数存储:带校验码与Code ID的EEPROM偏好管理

1. 项目概述CodedPreferences 是一个面向嵌入式系统的轻量级非易失性参数存储库&#xff0c;其核心设计目标是为资源受限的 MCU&#xff08;如 STM32F0/F1/L0/L1、nRF52、ESP32-C3 等&#xff09;提供具备编码校验能力的 EEPROM/Flash 偏好设置管理方案。与传统EEPROM.put()或裸…...

STM32F0串口DMA接收与发送工程实践

1. DMA在STM32串口通信中的工程价值与适用边界1.1 DMA机制的本质与硬件定位直接存储器访问&#xff08;Direct Memory Access&#xff0c;DMA&#xff09;是嵌入式系统中一种独立于CPU的数据搬运机制。其核心价值在于将数据在内存与外设之间进行高效传输时&#xff0c;完全释放…...

PROJECT MOGFACE创意编程:使用Processing进行AI生成艺术的可视化交互

PROJECT MOGFACE创意编程&#xff1a;使用Processing进行AI生成艺术的可视化交互 最近在探索AI与创意编程的结合&#xff0c;发现了一个特别有意思的玩法&#xff1a;用AI来生成艺术创作的“配方”&#xff0c;再用代码把它画出来。这就像是你告诉AI一个想法&#xff0c;它帮你…...

SMV_CAN_Bus:面向学生赛车的轻量级CAN应用层语义通信库

1. 项目概述 SMV_CAN_Bus 是加州大学洛杉矶分校&#xff08;UCLA&#xff09;Bruin Racing 团队为 Student Motorsport Vehicle&#xff08;SMV&#xff09;项目开发的专用 CAN 总线通信库。该库并非通用型 CAN 协议栈&#xff0c;而是面向赛车数据采集与分布式控制场景深度定…...

2026更新版!9个AI论文网站测评:本科生毕业论文写作必备工具推荐

在2026年&#xff0c;随着AI技术的不断迭代与学术写作需求的日益增长&#xff0c;越来越多的本科生开始关注并依赖AI工具来提升论文写作效率。然而&#xff0c;面对市场上种类繁多的AI论文网站&#xff0c;如何选择真正适合自己的工具成为一大难题。为此&#xff0c;笔者基于大…...

高效SRT字幕转Word解决方案:一键批量处理doc与docx格式

1. 为什么你需要SRT转Word工具 每次处理视频字幕时&#xff0c;你是不是也遇到过这样的烦恼&#xff1f;打开SRT文件&#xff0c;满屏都是时间码和序号&#xff0c;想要提取其中的文字内容&#xff0c;只能手动复制粘贴。我曾经帮朋友整理过一场两小时的访谈视频字幕&#xff0…...

UnityShader实战指南:从ShaderLab到Surface Shader的进阶之路

1. ShaderLab基础语法入门 第一次接触UnityShader时&#xff0c;我完全被ShaderLab的语法搞懵了。记得当时为了修改一个简单的颜色参数&#xff0c;花了整整一下午研究Properties块的写法。现在回头看&#xff0c;ShaderLab其实就像乐高积木的说明书&#xff0c;只要掌握几个核…...

从ME11到MEK1:SAP采购条件记录创建的BAPI性能对比(含RV_CONDITION_COPY完整示例)

SAP采购条件记录创建&#xff1a;ME11与MEK1的BAPI性能深度解析 在SAP采购模块中&#xff0c;条件记录创建是供应链管理的关键环节。传统ME11事务码虽然直观易用&#xff0c;但在批量处理和系统集成场景下&#xff0c;MEK1配合BAPI调用往往展现出更强大的技术优势。本文将深入剖…...

3D-MIMO信道模型的理论简介与MATLAB仿真分析

3D-MIMO(三维多输入多输出)是传统2D-MIMO的扩展&#xff0c;区别在于将天线阵列的维度从水平面拓展到垂直面&#xff0c;同时考虑电磁波在方位角(Azimuth Angle)和俯仰角(Elevation Angle)两个维度的传播特性。相比2D-MIMO&#xff0c;3D-MIMO能够利用垂直维度的波束赋形实现用…...

线程池(原理 + 应用)

一、什么是线程池线程池&#xff08;Thread Pool&#xff09;本质上就是&#xff1a;&#x1f449; 提前创建好一批线程&#xff0c;重复使用&#xff0c;避免频繁创建和销毁线程的开销简单理解&#xff1a;不用线程池&#xff1a;来一个任务 → 创建线程 → 执行 → 销毁 ❌&a…...