当前位置: 首页 > 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≤…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

Spring事务传播机制有哪些?

导语&#xff1a; Spring事务传播机制是后端面试中的必考知识点&#xff0c;特别容易出现在“项目细节挖掘”阶段。面试官通过它来判断你是否真正理解事务控制的本质与异常传播机制。本文将从实战与源码角度出发&#xff0c;全面剖析Spring事务传播机制&#xff0c;帮助你答得有…...

第21节 Node.js 多进程

Node.js本身是以单线程的模式运行的&#xff0c;但它使用的是事件驱动来处理并发&#xff0c;这样有助于我们在多核 cpu 的系统上创建多个子进程&#xff0c;从而提高性能。 每个子进程总是带有三个流对象&#xff1a;child.stdin, child.stdout和child.stderr。他们可能会共享…...