java类加载器,加载原理简述

本文只是对类加载器的加载原理做一简述,如有不对,请指正。

1. 加载之前

  1. 原理图
    java类加载器,加载原理简述_第1张图片
  2. 原理简述
    2.1 自己编写一个Myclass.java文件。
    2.2 在运行该文件时,首先通过javac Myclass.java 将该文件编译成Myclass.class文件(默认会在当前目录下)。
    2.3 通过类加载器将Myclass.class文件加载到JVM中的运行时数据区,再通过执行引擎将加载到运行时数据区的字节码文件

2. 加载时

  1. 原理图
    java类加载器,加载原理简述_第2张图片
  2. 加载源码
    首先判断当前类加载器是否有父类,如果有就调用父类加载器进行加载,否则就掉用Bootstrap类加载器进行加载,当Bootstrap类加载器进行加载失败时,抛出类为发现异常,就会调用当前类加载器进行加载。
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false); // 委托父类加载
                    } else {
                        c = findBootstrapClassOrNull(name); // 委托Bootstrap加载
                    }
                } 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();
                    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. 原理简述
    当类加载器加载Myclass.class时,会自底向上检查该Myclass.class是否已经被加载过,假如在Extension class loader处发现,该Myclass.class已经被加载过,则Myclass.class将不会被再次加载,而是会使用已经加载过的Myclass.class。加入检查到Bootstrap class loader 处也没有发现该Myclass.class被加载过,此时则会自顶向下进行尝试加载,首先Bootstrap class loader尝试在java_home/lib目录下找Myclass.class是否存在,存在就会被加载并完成Myclass.class的加载行为,否则继续向下尝试加载,当找到Custom class loader都没有找到Myclass.class时,则会抛出ClassNoFoundException异常。

3. 类加载之后

  1. 原理图
    java类加载器,加载原理简述_第3张图片
  2. 原理简述
    2.1 加载完成后,首先检查加载的类文件是否符合java规范和虚拟机规范
    2.2 分配所需内存,确定类属性、方法等所需的数据结构
    2.3 将常量池中的符号引用改变为直接引用
    2.4 初始化类的局部变量,为静态域赋值,执行静态初始化块。
  3. 限制
    3.1 下层的加载器能够看到上层加载器中的类,反之则不行
    3.2 类加载器可以加载一个类,但是不能卸载一个类。但是类加载器可以被删除或者被创建

你可能感兴趣的:(java基础)