Java虚拟机(JVM)-- 类加载器和双亲委派机制

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java虚拟机(JVM)-- 类加载器和双亲委派机制相关的知识,希望对你有一定的参考价值。

1. 类加载器和双亲委派机制


1.1 类加载器的作用

类加载器的作用是加载类文件到内存

类是模板,对象是具体的,类模板唯一,对象不唯一
在这里插入图片描述


1.2 类加载器测试

代码:

package packge01;

/**
 * @author TianJiao
 */
public class Person {
    public static void main(String[] args) {
        Person person01 = new Person();
        Person person02 = new Person();
        System.out.println("对象是不唯一的(new)");
        System.out.println("person01.hashCode(): " + person01.hashCode());
        System.out.println("person02.hashCode(): " + person02.hashCode());
        System.out.println("---------------------------------------------");
        System.out.println("模板是唯一的(Class)");
        System.out.println("person01.getClass().hashCode(): " + person01.getClass().hashCode());
        System.out.println("person02.getClass().hashCode(): " + person02.getClass().hashCode());
    }
}

运行结果:
在这里插入图片描述


1.3 类记载器的类型

在这里插入图片描述

  • 1.启动类(根)加载器(Bootstrap)
  • 2.扩展类加载器 (Ext)
  • 3.应用程序加载器 (App)
    在这里插入图片描述

1.4 双亲委派机制

Java去除了C++繁琐的指针和内存管理(全在JVM)里面,所有Java又被叫做C++--

  • 1.类加载器收到类加载的请求!
  • 2.将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器
  • 3.启动加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,通知子加载器进行加载
  • 4.重复步骤3
    class Not Found ~(.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理会先检查自己是否已经加载过,如果没有再往上。注意这个过程,知道到达Bootstrap classLoader之前,都是没有哪个加载器自己选择加载的。如果父加载器无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。)
    null : java调用不到~C、C++(Java底层是C、C++写的)
委托模型机制的工作原理很简单:当类加载器需要加载类的时候,先请示其Parent(即上一层
加载器)在其搜索路径载入,如果找不到,才在自己的搜索路径搜索该类。这样的顺序其实就
是加载器层次上自顶而下的搜索,因为加载器必须保证基础类的加载。之所以是这种机制,
还有一个安全上的考虑:如果某人将一个恶意的基础类加载到jvm,委托模型机制会搜索其父
类加载器,显然是不可能找到的,自然就不会将该类加载进来。(这种设计有个好处是,如
果有人想替换系统级别的类:String.java。篡改它的实现,在这种机制下这些系统的类已经被
Bootstrap classLoader加载过了(为什么?因为当一个类需要加载的时候,最先去尝试加载
的就是BootstrapClassLoader),所以其他类加载器并没有机会再去加载,从一定程度上防
止了危险代码的植入。

测试:

package packge01;

/**
 * @author TianJiao
 */
public class Person {
    public static void main(String[] args) {
        Person person01 = new Person();
        System.out.println(person01.getClass().getClassLoader());// App
        System.out.println(person01.getClass().getClassLoader().getParent());// Ext
        System.out.println(person01.getClass().getClassLoader().getParent().getParent());// null (Java底层是C,C++写的)
    }
}

运行结果:

在这里插入图片描述

验证Java底层是C、C++写的
在这里插入图片描述



以上是关于Java虚拟机(JVM)-- 类加载器和双亲委派机制的主要内容,如果未能解决你的问题,请参考以下文章

Java中类加载器和双亲委派机制

JVM探究之 —— 类加载器-双亲委派模型

图解类加载器和双亲委派机制,一看就懂

JVM之类加载器加载过程及双亲委派机制

JVM之类加载器加载过程及双亲委派机制

jvm 双亲委派模式