微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JVM双亲委派模型及其优点

JVM双亲委派模型及其优点

什么是双亲委派模型?

双亲委派模型

​ 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。

简单来说就是:

  • 首先从底向上检查类是否已经加载过
  • 如果都没有加载过的话,那么就自顶向下的尝试加载该类

为什么使用双亲委派模型?

1.避免字节码重复加载

采用双亲委派模式的是好处是java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。

2.程序更加安全,核心api不会被替换

​ 假设通过网络传递一个名为java.lang.Integer的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的java.lang.Integer,而直接返回已加载过的Integer.class,这样便可以防止核心API库被随意篡改。相同的class文件被不同的classloader加载就是不同的两个类。

双亲委派模型类加载器分类

1、启动类加载器(Bootstrap)C++写的
2、扩展类加载器(Extension)JAVA
3、应用程序类加载器(AppClassLoader)也叫做系统类加载器,加载当前应用的classpath下的所有类。
4、用户自定义加载器:
java.lang.classLoader的子类,用户可以定制类的加载方式。

打印加载器的加载路径:

import sun.misc.Launcher;
import sun.misc.URLClasspath;
import java.net.URL;
import java.net.urlclassloader;

public class Example {
    public static void main(String[] args) {
        //打印启动类加载器的加载路径
        URLClasspath bootstrapClasspath = Launcher.getBootstrapClasspath();
        for(URL url : bootstrapClasspath.getURLs()){
            System.out.println(url.getPath());
        }
        //打印扩展类加载器的加载路径
        urlclassloader extClassLoader = 		(urlclassloader)ClassLoader.getSystemClassLoader().getParent();
        for(URL url : extClassLoader.getURLs()) {
            System.out.println(url.getPath());
        }
        //打印应用程序类加载器加载路径
        urlclassloader appClassLoader = (urlclassloader)ClassLoader.getSystemClassLoader();
        for(URL url : appClassLoader.getURLs()) {
            System.out.println(url.getPath());
        }
    }
}

打印加载器实例对象:

BootStrapClassLoader 是一个纯的C++实现,没有对应的java类。如果一个类的classloader是null。证明其是由BootStrapClassLoader 加载的。

public class Example {
    public static void main(String[] args) {
        System.out.println(Example.class.getClassLoader());
        System.out.println(Example.class.getClassLoader().getParent());
        System.out.println(Example.class.getClassLoader().getParent().getParent());
    }
    
/*  输出:
	sun.misc.Launcher$AppClassLoader@18b4aac2
    sun.misc.Launcher$ExtClassLoader@4554617c
	null*/

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐