ClassLoader

一、类加载过程
Class文件需要加载到虚拟机中之后才能运行和使用。
包括主要三步:加载->链接->初始化,链接过程又包括三步:验证->准备->解析。
加载
将class字节码文件加载到内存中,并将这些数据转换成方法区中的运行时数据(静态变量、静态代码块、常量池等),在堆中生成一个Class类对象代表这个类(反射原理),作为方法区类数据的访问入口。
链接
验证
目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身安全。主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证。
准备
正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配
解析
虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程
初始化
- 执行类构造器< clinit >()方法的过程,将所有类变量的赋值动作和静态代码块的语句运行
- 初始化一个类时,如果其父类还没有初始化,则先触发其父类的初始化
- 虚拟机会保证一个类的< clinit >()方法在多线程环境中被正确加锁和同步
二、类加载器
- 启动(Bootstrap)类加载器或根加载器
- 启动类加载器主要加载的是JVM自身需要的类,这个类加载使用C++语言实现的,是虚拟机自身的一部分,它负责将 < JAVA_HOME >/lib路径下的核心类库或-Xbootclasspath参数指定的路径下的jar包加载到内存中,注意必由于虚拟机是按照文件名识别加载jar包的,如rt.jar,如果文件名不被虚拟机识别,即使把jar包丢到lib目录下也是没有作用的(出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类)。
- 扩展(Extension)类加载器
- 扩展类加载器是指Sun公司(已被Oracle收购)实现的sun.misc.Launcher$ExtClassLoader类,由Java语言实现的,是Launcher的静态内部类,它负责加载< JAVA_HOME >/lib/ext目录下或者由系统变量-Djava.ext.dir指定位路径中的类库,开发者可以直接使用标准扩展类加载器。
- 应用程序加载器
- 也称应用程序加载器是指 Sun公司实现的sun.misc.Launcher$AppClassLoader。它负责加载系统类路径java -classpath或-D java.class.path 指定路径下的类库,也就是我们经常用到的classpath路径,开发者可以直接使用系统类加载器,一般情况下该类加载是程序中默认的类加载器,通过ClassLoader#getSystemClassLoader()方法可以获取到该类加载器。
三、双亲委派机制
某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
AppClassLoader的父类加载器为ExtClassLoader ExtClassLoader的父类加载器为null,null并不代表ExtClassLoader没有父类加载器,而是 BootstrapClassLoader 。因为java底层是由C语音编写的,所以返回为null。
- 本文标题:ClassLoader
- 本文作者:Kang
- 创建时间:2021-02-28 17:24:15
- 本文链接:ykhou.github.io2021/02/28/ClassLoader/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!