class文件加载过程、ClassLoder类加载器及ClassLoder双亲委托机制
编程语言演变
类加载大致流程
类加载到JVM流程结构图
加载Mayikt.class的整个流程及jvm结构图;
1. 线程共享的为颜色,线程私有的为
颜色;
2. jdk1.8及之后版本方法区改名为元空间;
什么是类加载器
将我们class文件读取到内存中。
类加载器加载的过程
类加载器加载我们的class文件,并且经历过验证、准备、解析,在初始化我们该类。
读取class文件来源那些
- 自己写的java源代码 编译成class文件 硬盘读取
- 通过网络的方式下载class文件
- War、Jar 解压之后都是class文件
- 从数据库中读取class文件
- Java动态代理模式 反射/cglib 生成代理class
ClassLoader类加载器四种分类
- 启动类加载器 $JAVA_HOME/jre/lib下的文件;核心包:string.反射 代表rt.jar C语言;如果是启动类加载器读取的,获取classloader 是null
- 扩展类加载器JAVA_HOME/jre/lib/ext目录中的文件 java写;
- 应用类加载器 读取我们当前项目中定义的引入jar包、写的class文件 java写;
- 自定义类加载器 读取class文件范围 都是属于自定义 java写的。
类加载器
注意:每个类加载器有自己不同的职责:读取class文件范围。
类加载器触发条件
1.new 对象;
2.调用静态方法的时候;
3.main;
4.class.forname;
5.只要子类被加载的时候,父类也会被加载;
类加载器加载该类,不一定会初始化,
一个类一旦初始化的情况下,该类就一定被加载。
类加载器的双亲委派机制
首先在我们类加载器分为四种 自定义类加载器、应用类加载器、扩展类加载器、启动类加载器。
当一个类加载器收到请求之后,首先会依次向上查找到最顶层类加载器(启动类加载器),依次向下加载class文件,如果已经加载到class文件,子加载器不会加继续加载该class文件。
双亲委派机制好处
从下向上查找到最顶端的“启动类加载器”读取class文件,只要“启动类加载器”读取成功之后,以后不会再向下查找其它类加载器。
好处:目的就是为了防止开发者自定义的类与jdk定义源码类产生冲突问题,保证该类在内存中的唯一性。
冲突的包名和类名,优先按照类加载器层级进行加载。
例如:用户自定义java.long.object包,类名叫做Object;这样会和jdk自带的Object重启,按理说启动项目应该会报错;
但是事实启动项目是不会报错的,原理就是委托机制,首先从顶端类加载器找到了($JAVA_HOME/jre/lib目录下)jdk自带的Object类,就会加载近来,不会再往下找。
类加载器源码解读
Launcher 设定类加载器的依赖关系