这是类加载的过程,加载的类是放到了 JVM 的元数据空间,也就是永久代。
• 加载:根据查找路径找到相应的 class 文件然后导入;
• 检查:检查加载的 class 文件的正确性;
• 准备:给类中的静态变量分配内存空间;
• 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
• 初始化:对静态变量和静态代码块执行初始化工作。
概述
通过全限定名来加载生成 class 对象到内存中,然后进行验证这个 class 文件,包括文件格式校验、元数据验证,字节码校验等。准备是对这个对象分配内存。解析是将符号引用转化为直接引用(指针引用),初始化就是开始执行构造器的代码
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备 (Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using) 和卸载(Unloading)7 个阶段。其中准备、验证、解析 3 个部分统称为连接(Linking)。
加载、验证、准备、初始化和卸载这 5 个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 语言的运行时绑定(也称为动态绑定或晚期绑定)。
java 类加载需要经历下面5 个过程:
加载
查找并加载类的二进制数据(把 class 文件里面的信息加载到内存里面)
加载时类加载的第一个过程,在这个阶段,将完成一下三件事情:
验证
把内存中类的二进制数据合并到虚拟机的运行时环境中
验证的目的是为了确保 Class 文件的字节流中的信息不会危害到虚拟机. 在该阶段主要完成,
以下四钟验证:
准备
准备阶段是为类的静态变量分配内存并将其初始化为默认值,这些内存都将在方法区中进行分配。准备阶段不分配类中的实例变量的内存,实例变量将会在对象实例化时随着对象一起分配在 Java 堆中。
public static int value=123;// 在准备阶段 value 初始值为 0 。在初始化阶段才会变为 123 。
解析
该阶段主要完成符号引用到直接引用的转换动作。解析动作并不一定在初始化动作完成之前,也有可能在初始化之后。
把类中的符号引用转化为直接引用(比如说方法的符号引用,是有方法名和相关描述符组成,在解析阶段,JVM 把符号引用替换成一个指针,这个指针就是直接引用,它指向该类的该方法在方法区中的内存位置)
初始化
为类的静态变量赋予正确的初始值。当静态变量的等号右边的值是一个常量表达式时,不会调用 static 代码块进行初始化。只有等号右边的值是一个运行时运算出来的值,才会调用 static 初始化。
初始化时类加载的最后一步,前面的类加载过程,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的 Java 程序代码。