谈谈类加载器中的双亲委派机制

本博文中所讨论的JVM只是自己看书和教程的个人理解,不太严谨,严谨需要另找详细的资料,对细节把控很到位。

本博文环境:

System OS: Windows10 1909
JDK-Version: 1.8.0_202
JVM: Java HotSpot™ 64-Bit Server VM (build 25.202-b08, mixed mode)
IDE: IDEA2021.3

一,前提

首先,先写一段代码:

package java.lang;

public class String {

	public static void main(String[] args) {
		System.out.println("test");
	}
}

发现错误:

二,双亲委派工作原理

明明看似是一个简单的普通的类,定义一个java.lang.String中的main方法提示找不到,问题在于双亲委派机制。按照博文:JVM中类加载器的分类理解与剖析可以得到以下这种层次关系:
在这里插入图片描述
JAVA虚拟机对Class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象,而且加载某个类的class文件时,JAVA虚拟机采用的是双亲委派模式,即是吧请求交给父类处理,是一种任务委派模式。
在这里插入图片描述

在这里插入图片描述

工作原理:
1) 如果一个类加载器收到了请求,并不会马上的先去加载,而是把这个请求委托给上一层加载器去执行。
2) 如果上一层加载器还存在上一层加载器,则会进一步向上进行委托,类似于递归的思想,请求最终就会到达引导类加载器
3)上一层加载器可以完成类加载任务,成功返回,如果上一层的加载其无法完成加载任务,下一层加载器才会有机会去加载。
这就是双亲委派。

三,双亲委派的优势

1. 避免重复加载
两个类A和类B都要加载System类: 如果不用委托而是自己加载自己的,那么类A就会加载一份System字节码,然后类B又会加载一份System字节码,这样内存中就出现了两份System字节码。 如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的System就能在Bootstrap中找到然后加载,如果此时类B也要加载System,也从Bootstrap开始,此时Bootstrap发现已经加载过了System那么直接返回内存中的System即可而不需要重新加载,这样内存中就只有一份System的字节码了。
2. 保护程序安全,防止核心API被随意篡改。
如果你自定义一个类,是java.lang,则在当前包下所定义的都不能正确的执行,这就是一个保护程序安全的机制。

对于开始问题的解答:
自定义String类,但是在加载自定义String类的时候会率先使用引导类加载器加载,而引导类加载器在加载的过程中会先加载jdk自带的文件(rt.jar包中的java\lang\String.class),报错信息说没有main方法,就是应为加载的是rt.jar包中的String
类,这样可以保证对java核心源代码的保护,这既是沙箱安全机制
推荐阅读与参考:
[1] Java类加载器和双亲委派机制
类加载器如何打破双亲委派加载机制(SPI原理)
通俗易懂的双亲委派机制

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值