初探JVM02

初探JVM02 -双亲委派机制

(博客来自本人csdn原创)
什么是双亲委派机制:
当某个类加载器要加载一个.class文件时候,它首先把这个请求委托给父加载器去完成,一直向上委托,递归操作,如果上级的类加载器没有加载 ,它就自己加载,直到启动类加载器;
代码测试:
在这里插入图片描述

  1. String 默认情况下是启动类加载器进行加载的,假设我也自定义一个 String。你会发现自定义的String 可以正常编译,但是无法被加载运行。
  2. 这是因为申请自定义String加载时,总是启动类加载器,而不是自定义类加载器,也不会是其他的类加载器。
  3. 双亲委派机制可以确保Java核心库所提供的类,不会被自定义的类所替代。

来看一下Java执行代码的相关流程

在这里插入图片描述

假设要执行A类的main方法

  1. 启动虚拟机 (c++负责创建)

  2. 创建一个引导类加载器实例(c++实现)

  3. C++调用Java代码,创建JVM启动器,实现sun.misc.Launcher

查看源代码快捷键是 crtrl+鼠标左键
查看一个类的全部方法是 alt+7
在这里插入图片描述

在这里插入图片描述

  1. sun.misc.Launcher.getLauncher() 获取运行类自己的加载器ClassLoader -->是AppClassLoader,通过上图源码可知

5.获取到ClassLoader 后调用loadClass("A") 方法加载运行的类A

6.加载完成执行A类的main方法

7.程序运行结束

8.JVM销毁

Launcher构造函数

,我们看一下它的构造函数干了什么
在这里插入图片描述

  1. Launcher构造方法内部,创建了两个类加载器,分别是sun.misc.Launcher.ExtClassLoader(扩展类加载器)和sun.misc.Launcher.AppClassLoader(应用类加载器)

  2. JVM 默认使用Launcher的getClassLoader()方法返回的类加载器AppClassLoader来加载我们的应用程序。

源码解析ClassLoader&loaderClass

loadClass实现了双亲委派的功能,我们有必要深入了解一下

既然都是向上委托向上查找,我们来看一下应用程序类加载器AppClassLoader加载类的双亲委派机制源码,AppClassLoader的loadClass的方法最终会调用其父类的ClassLoader的loadClass方法

/*
一些注释就不添加了!懒!
*/
在这里插入图片描述
在这里插入图片描述

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

双亲委派机制的优点
1:沙箱安全机制:表现为自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
在这里插入图片描述
2.避免类的重复加载,当父类已经加载了此类,就没必要再加载一次。保证了加载类的唯一性!

加载过程再了解

在这里插入图片描述

posted @ 2021-01-06 16:04  xiaozhounandu  阅读(53)  评论(0编辑  收藏  举报