文章目录
1、什么是Classloader
Classloader顾名思义,即是类加载。虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。了解java的类加载机制,可以快速解决运行时的各种加载问题并快速定位其背后的本质原因。
2、Classloader的作用
3、Classloader的加载过程
类从被加载到虚拟机内存到被卸载,整个完整的生命周期包括:类加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中验证,准备,解析三个部分统称为连接。接下来我们可以详细了解下类加载的各个过程。
三、Java默认提供的三个ClassLoader
1.BootStrap ClassLoader :
启动类加载器,是Java 类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等
2.Extension ClassLoader :
扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar.
3.App ClassLoader :
系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件。
四、ClassLoader加载类的原理
ClassLoader使用的是双亲委派来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。
JVM是按需动态加载,采用双亲委派机制
Classloader的双亲委托机制是指多个类加载器之间存在父子关系的时候,某个class类具体由哪个加载器进行加载的问题。其具体的过程表现为:当一个类加载的过程中,它首先不会去加载,而是委托给自己的父类去加载,父类又委托给自己的父类。因此所有的类加载都会委托给顶层的父类,即Bootstrap Classloader进行加载,然后父类自己无法完成这个加载请求,子加载器才会尝试自己去加载。使用双亲委派模型,Java类随着它的加载器一起具备了一种带有优先级的层次关系,通过这种层次模型,可以避免类的重复加载,也可以避免核心类被不同的类加载器加载到内存中造成冲突和混乱,从而保证了Java核心库的安全。
下图为类加载的一个全过程:
用比较通俗的话来解释这个过程,当有一个类需要被加载时,首先要判断这个类是否已经被加载到内存,判断加载与否的过程是有顺序的,如果有自己定义的类加载器,会先到custom class loader 的cache(缓存)中去找是否已经加载,若已加载直接返回结果,否则到App的cache中查找,如果已经存在直接返回,如果不存在,到Extension中查找,存在直接返回,不存在继续向父加载器中寻找直到Bootstrap顶层,如果依然没找到,那就是没有加载器加载过这个类,需要委派对应的加载器来加载,先看看这个类是否在自己的加载范围内,如果是直接加载返回结果,若不是继续向下委派,以此类推直到最下级,如果最终也没能加载,就会直接抛异常 ClassNotFoundException,这就是双亲委派模式。