021-JVM-双亲委派机制

210 阅读4分钟

前面我们知道类的加载均是由 ClassLoader 加载进入内存的,那么这里类的加载有没有三六九等呢?加入我自己定义一个 java.lang.String 类,偷偷摸摸的写一些代码,去坑别人迷惑别人可以吗?

  • 答案是不可以的,这种安全问题不会出现,原因就是 jvm 加载类的时候有双亲委派机制
  1. Java 虚拟机对 Class 文件采用的是按需加载的方式
  2. 也就是说当需要使用该类时才会将它的 class 文件加载到内存生成 Class 对象。
  3. 而且加载某个类的 class 文件时, Java 虚拟机采用的是双亲委派模式
  4. 即把请求交由父类类处理, 它是一种任务委派模式。


工作原理:

  1. 如果一个类加载器收到了类加载请求, 它并不会自己先去加载, 而是把这个请求委托给父类的加载器去执行;
  2. 如果父类加载器还存在其父类加载器, 则进一步向上委托, 依次递归。请求最终将到达顶层的启动类加载器;
  3. 如果父类加载器可以完成类加载任务, 就成功返回, 倘若父类加载器无法完成此加载任务, 子加载器才会尝试自己去加载, 这就是双亲委派模式。

家里穷买了一个杨桃

  1. 小孙子小明先拿到,想吃呢?一看爸爸在,就给了爸爸,说爸爸,你吃吧
  2. 小明爸爸结果杨桃正想吃呢,想到了孩子的爷爷还没吃呢,转手就递给了小明爷爷,说爸爸,你吃吧。
  3. 小明爷爷结果杨桃,一看这么新鲜,舍不得吃,递给了自己儿子,说儿子,你吃吧。
  4. 小明爸爸接过杨桃,一看,觉得还是让小明吃好,就递给了小明。
  5. 小明结果杨桃,高兴的吃了起来。

看见了吧
杨桃就是要加载的类
只要爸爸和爷爷任何人想吃杨桃,就轮不到小明了。

  1. AppClassLoader 接过任务,要加载,一看爸爸 ExtClassLoader 在,就交给了爸爸 ExtClassLoader。
  2. ExtClassLoader 结果任务,要加载,一看爸爸 BootStrapClassLoader 在,就交给了爸爸 BootStrapClassLoader。
  3. BootStrapClassLoader 一看这个类确实在自己的负责范围之内。就记载了。
    这样就算程序员故意写一个 java.lang.String 也没法加载,因为爷爷要先加载,且加载自己负责的一亩三分地里的 java.lang.String。而不是程序员定义的 java.lang.String, 因为程序员定义的 java.lang.String 不在 bootStrapClassLoader 职责范围之内。

java.lang.StringSSS 这个类很特殊。程序员够狠,定义了一个不存在的类。

  1. AppClassLoader 接过任务,要加载,一看爸爸 ExtClassLoader 在,就交给了爸爸 ExtClassLoader。
  2. ExtClassLoader 结果任务,要加载,一看爸爸 BootStrapClassLoader 在,就交给了爸爸 BootStrapClassLoader。
  3. BootStrapClassLoader 一看这个类要加载,先在自己的职责范围内找了一圈发现没有,这个类,就把加载全给了 ExtClassLoader,说你加载吧,我这里没有这个类
  4. 此时 ExtClassLoader 拿到这个类后,才有资格去查一下自己的职责范围内有么有这个类,第一次拿到的时候必须先让给他爸爸,连查找一下都不行。于是查找了一圈发现没有,就把加载权给了 AppClassLoader
  5. AppClassLoader 结果权限后,一查,果然在,就加载了。
    这个过程就是这样,这就是双亲委派机制。

双亲委派就是子 -> 爸 -> 爷;然后爷 -> 爸 -> 子的过程这两圈就叫双亲委派。别误会啊。不是别的双亲委派。

那么上文说达到的各个类加载器的责任范围是什么呢?且听下回分解!

自律的艰辛总甜过懊悔的苦果!
专注于 java 后端技术及解决方案,善于总结,分享!
自律的艰辛总甜过懊悔的苦果!
专注于 java 后端技术及解决方案,善于总结,分享!
自律的艰辛总甜过懊悔的苦果!
专注于 java 后端技术及解决方案,善于总结,分享!