JVM系列之双亲委派机制的实现和作用

双亲委派机制的定义

当某个类加载器需要加载class文件时,它会先把这个加载任务委派给他的父级类加载器,递归这个操作,如果上级的类加载器无法加载,自己才会去加载这个类,如下图:

双亲委派机制的实现

下面是java.lang.ClassLoader中loadClass方法的源码,具体实现对照代码解释。

当一个class文件需要被加载时(如果不考虑自定义类加载器),进入AppClassLoader中,首先检查是否加载过,如果有就无需加载了。如果没有,自己先不加载,去调用Extension ClassLoader的loadClass方法。Extension ClassLoader中同理会先检查自己是否已经加载过,如果没有,则去调用Bootstrap classLoader的loadClass方法,这里就没有父级了,Bootstrap classLoader就会看自己是否可以加载,如果可以就加载返回,如果无法加载,就会顺次下沉到子加载器Extension ClassLoader、AppClassLoader去加载,如果没有任何加载器能加载,就会抛出ClassNotFoundException。

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
	synchronized (getClassLoadingLock(name)) {
		//首先检查这个class是否已经被加载了
		Class<?> c = findLoadedClass(name);
		if (c == null) {
			long t0 = System.nanoTime();
			try {
				if (parent != null) {
					c = parent.loadClass(name, false);
				} else {
					c = findBootstrapClassOrNull(name);
				}
			} catch (ClassNotFoundException e) {
				//如果未从非空的父加载器中找到类throw ClassNotFoundException
			}
			if (c == null) {
				//如果仍然没有找到,那么调用自身的findClass来加载类.
				long t1 = System.nanoTime();
				c = findClass(name);
				//this is the defining class loader; record the stats
				sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
				sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
				sun.misc.PerfCounter.getFindClasses().increment();
			}
		}
		if (resolve) {
			resolveClass(c);
		}
		return c;
	}
}

双亲委派机制的作用

1、保证核心class文件的安全性,如果有人篡改替换了系统级别的类,但是在这种机制下这些系统的类已经被Bootstrap ClassLoader加载过了,所以并不会再去加载,从一定程度上防止了危险代码的植入,从而保证底层class的执行安全。

2、防止重复加载同一class文件。通过委派机制向父级ClassLoader询问,如果加载过了,就不用再加载一遍,保证只会加载一份。

如何打破双亲委派机制

在继承自ClassLoader的自定义类加载器中重写loadClass方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值