JVM从源码分析类加载机制

本文深入探讨了Java中的类加载器,包括引导类加载器、扩展类加载器和应用程序类加载器的工作原理。通过源码分析揭示了类加载器的实例化流程,特别是AppClassLoader和ExtClassLoader之间的关系。此外,文章详细阐述了双亲委派机制,解释了其在防止重复加载和确保安全方面的作用,并通过代码展示了其实现过程。最后,讨论了双亲委派机制带来的好处,如防止类的版本冲突和保证核心类库的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三种类加载器(除自定义类加载器)

1.引导类加载器(BootstrapClassLoader):加载JAVA_HOME/lib下的类包
2.扩展类加载器(ExtClassLoader):加载JAVA_HOME/lib/ext 下的类包
3.应用程序类加载器(AppClassLoader):加载ClassPath路径下的类包

流程图在这里插入图片描述

源码分析 launcher 的实例化流程

1.AppClassLoader 和 ExtClassLoader 都继承URLClassLoader在这里插入图片描述

2.getLauncher() 获取的是一个 单例类 Launcher 对象,保证了每一个虚拟机只有一个 Launcher
则
3…程序执行的结果说明了 自定义类 User的 类加载器 是 AppClassLoader, AppClassLoader的父加载器是ExtClassLoader , ExtClassLoader 的父加载器是 null,下面源码解释一下为什么是这样**

在这里插入图片描述
###############################################################################

在Launcher的构造函数中,先创建ExtClassLoader 对象 var1,然后在创建AppClassLoader对象的时候将var1赋值给 AppClassLoader 的父加载器
在这里插入图片描述

###############################################################################

URLClassLoader 继承了 ClassLoader在这里插入图片描述

###############################################################################

ClassLoader 构造函数中 初始化 父构造器 ClassLoader
在这里插入图片描述

###############################################################################

ExtClassLoader 的构造函数中会把 null 赋值给 parent
在这里插入图片描述

###############################################################################

而AppClassLoader 在初始化的时候会把 var2 也就是 ExtClassLoader 对象赋值给 parent
而
在这里插入图片描述
###############################################################################

4.注意 : 很多人看双亲委派原则都以为 AppClassLoader 的父类是 ExtClassLoader ,ExtClassLoader 的父类的 BootStrapClassloader,其实这是错的. 源码中我们可以看到 AppClassLoader 和 ExtClassLoader的父类都是URLClassLoader.我们说 AppClassLoader的父加载器是 ExtClassLoder ,ExtClassLoader的父加载器是BootStrapClassLoader,

下面讲双亲委派机制从源码上 来解释这一点

双亲委派机制原理

简单的说,就是子 类加载器 将加载任务丢给父加载器,父加载器加载不到了才返回给子加载器加载

双亲委派机制源码分析

上面流程图说到,类的加载都是 ClassLoader类的 loadClass函数
当我们执行一个main函数的时候 ,比如这一行

public static void main(String[] args) {
        Math math = new Math();
        math.excuteV();
    }

步骤一:
在这里插入图片描述

步骤二:
在这里插入图片描述
在这里插入图片描述

步骤三:接着往下走

进入findClass函数,findClass函数是需要子类去实现的,因为AppClassLoader 和 ExtClassLoader 都继承URLClassLoader,所以我们进入 URLClassLoader 的 findClass函数
在这里插入图片描述
在这里插入图片描述
这个defineClass函数比较核心,是将Resource 资源 加载到类对象中

步骤四:
在这里插入图片描述

以上就实现了双亲委派机制

双亲委派机制的好处是啥呢?
1.可以防止重复加载数据 ,比如 AppClassLoader 加载了数据后 ExtClassLoader就不能加载相同数据了
2.沙箱安全机制:比如我自己写了一个跟 jdk一毛一样的类 都叫 java.lang.String ,这样 jvm只能由Bootstrap加载器加载到 jdk自带的java.lang.String ,而忽略掉自己写的 java.lang.String

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值