JVM类加载器ClassLoder加载流程,以及双亲委派机制(源码剖析,通俗易懂)

JVM类加载器概述

在这里插入图片描述

从上图容易看出,类加载器就是把java程序生成的Class字节码文件的信息加载进JVM的一个类,每一个java类对象都对应着一个Class字节码文件,这些Class文件存储这java类对象的结构信息,通过类加载器把这些Class字节码文件转化为对应的class类对象,也就是java类对象->Class类对象的过程,这样的Class类才是能被虚拟机直接使用的Java类型

类加载器的种类(主要是3种)

在这里插入图片描述

  • 1.启动类加载器(BootStrap)------------>加载路径JRE/lib/rt.jar
    也就是说需要加载JRE/lib/rt.jar包下的Class类对象时,由BootStrap加载器完成,JRE/lib/rt.jar主要存放的是Java自带的类对象(例如String,Integer,Double等)
  • 2.扩展类加载器(ExtClassLoader)----------->类加载路径JRE/lib/ext/.jar
    也就是说需要加载JRE/lib/ext/
    .jar包下的Class类对象时,由ExtClassLoader加载器完成
  • 3.应用类加载器(AppClassLoader)----------->类加载路就CLASSPATH路径下的所有jar
    例如你添加了jar包依赖到CLASSPATH路径下,这些依赖jar包中的Class类对象由AppClassLoader加载器完成

双亲委派机制

双亲委派机制是Class类对象的加载机制,IDEA中打开java.lang.ClassLoader类的源码

 protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded(检查目前这个类加载器是否加载了class)
            Class<?> c = findLoadedClass(name);
            //如果没有加载,也就是c为null
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    //如果父类加载器不为空,从父类开始寻找c是否被加载
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } 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(到了最上层BootStrap加载器任然没有找到c,调用最上层的findclass方法查找c是否被加载)
                    // 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;
        }
    }

从源码中我们可以发现,当查找一个Class类对象是否被加载进JVM时,首先从最下层的子类加载器开始判断,如果没由被加载再向上层的父类加载器继续判断,直到发现被加载为止,如果没被加载就从上往下的类加载器的类加载路径中去找是否由该Class对象,如果有,加载进JVM,通俗的理解就是说,判断Class类对象是否被加载顺序从AppClassLoader->ExtClassLoader->BootStrap,加载Class类对象的顺序从BootStrap->ExtClassLoader->AppClassLoader,如果还不理解没关系,看下图
在这里插入图片描述
该图是来源于某网络博主,如果有冒犯到,还望告知,谢谢博主,仅限于学习,不商用

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值