JVM把class文件加载的内存,并对数据进行校验、转换解析和初始化,最终形成JVM可以直接使用的Java类型的过程就是加载机制。
类加载生命周期
- 加载(Loading)
- 验证(Verifycation)
- 准备(Preparation)
- 解析(Resolution)
- 初始化(Initialization)
- 使用(Using)
- 卸载(Unloading) 其中验证、准备、解析这三个阶段统称为连接。加载、验证、准备、初始化、卸载这五个阶段顺序是确定的。
- 加载
在加载阶段,虚拟机需要完成三件事情:- 通过一个类的全限定名来获取定义此类的二进制字节流。
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
- 在内存中生成一个代表这个类的java.lang.class的对象,作为方法区这个类的各种数据的访问入口。
- 验证
验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不回危害虚拟机的安全。验证阶段一共包含四步:文件格式验证、愿数据验证、字节码验证、符号引用验证。 - 准备
准备阶段是为类变量分配内存并设置初始值的阶段,这些变量所使用的内存都在方法区中。
public static int value=123;这个变量在准备阶段会初始化为0而不是123,因为这个时候尚未执行任何java方法,将value赋值为123是在putstatic指令被程序编译之后。
public static final int value=123;而这个会在准备阶段之后value就被初始化为123。 - 解析
解析阶段是将常量池中的符号引用替换成直接引用的过程。 - 初始化
初始化阶段是真正开始执行类中定义的java代码。在准备阶段,类变量已经赋值了一次系统要求的初始值,而在初始化阶段,则根据具体实际的值去初始化。
类加载器
- Bootstrap ClassLoader
- Extension ClassLoader
- Application ClassLoader
- Custom ClassLoader
双亲委派模型
双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应该有自己的父类加载器。这些父子类加载器之间的关系不会以继承来实现,而是使用组合来实现。
双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。