深入解析JVM-类加载机制

并发专题

深入解析JVM-类加载机制

深入解析JVM-Java对象头组成

深入JVM内置锁 synchronized 底层

深入理解JMM-Java内存模型

深入理解JMM-volatile原理分析

并发编程-深入解析CAS

并发编程-深入AQS原理

目录

类加载器加载的过程

类加载器的分类

双亲委派机制

 双亲委派源码解析

双亲委派机制好处 

如何破坏双亲委派


类加载器加载的过程

类加载过程会经过:

加载 、验证、准备、解析、初始化、使用、卸载

各阶段解析:

加载:在硬盘查找并通过IO读取字节码文件,在加载节点生成这个类的java.class.Class对象

验证:校验字节码文件的准确性

解析:讲符号引用替换为直接引用

初始化:对类的静态变量初始化为指定的值,执行静态代码块

类加载器的分类

1、启动类(Bootstrap)加载器:加载JVM需要的类,会加$JAVA_HOME/jre/lib下的文件 底层是C语言实现

2、扩展类(Extension)加载器:由sun.misc.LauncherExtClassLoader实现,他会加载JAVA_HOME/jre/lib/ext目录中的文件(或由System.getProperty(“java.ext.dirs”)所指定的文件)。底层是Java实现

3、应用类(AppClassLoader)加载器:由sun.misc.Launcher$AppClassLoader实现。会加载classpath下的class及jar包。底层是java实现

4、自定义加载器

双亲委派机制

当我们类加载器收到一个请求的时候,首先会依次向上查找最顶层没有父类的类类加载器 (启动类加载器),依次向下读取class文件,如果该类加载器已经读取到class文件的时候,子节点不会再继续读取

 双亲委派源码解析

  1. 首先,检查一下指定名称的类是否已经加载过,如果加载过了,就不需要再加载,直接返回。
  2. 如果此类没有加载过,那么,再判断一下是否有父加载器;如果有父加载器,则由父加载器加载(即调用parent.loadClass(name, false);).或者是调用bootstrap类加载器来加载。
  3. 如果父加载器及bootstrap类加载器都没有找到指定的类,那么调用当前类加载器的findClass方法来完成类加载。

//ClassLoader的loadClass方法,里面实现了双亲委派机制
protected Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException
{
    synchronized (getClassLoadingLock(name)) {
        // 检查当前类加载器是否已经加载了该类
        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) {
                // 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();
                //都会调用URLClassLoader的findClass方法在加载器的类路径里查找并加载该类
                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;
    }
}

双亲委派机制好处 

为了防御开发者为定义的类与jdk定义源码类产生冲突问题,保证该类在内存中的唯一性

如何破坏双亲委派

1、自定义类加载器 重写loadClass方法

2、Spi机制绕开loadClass方法。当前线程设定关联类加载器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

janyxe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值