JVM类加载过程

JVM类加载分为5个过程:加载,验证,准备,解析,初始化,使用,卸载,以下图所示: java

加载过程

加载

加载是指查找字节流并据此建立类的过程。git

  • (1) 数组类没有对应的字节流,它是由JVM根据元素类型和维度,建立的。
  • (2) 除了数组类,其余类都是JVM借助BootStrap ClassLoaderClassLoaderExtClassLoaderAppClassloader等类加载器来查找字节流并建立的。
  • (3) 在JVM中类的惟一性是由类的全名和类加载器肯定的,相同的class文件被不一样的类加载器加载生成的两个类是不一样的。

链接

链接是指将建立好的类放入JVM并使之可以很好的执行的过程。
它可分为验证、准备、解析三个步骤。github

  • (1) 验证阶段是为了保证建立的类可以知足JVM的约束条件,例如:jdk版本验证。
  • (2) 准备阶段的目的是为建立的类的静态字段分配内存,对静态字段具体的初始化会在初始化阶段进行。
    部分虚拟机在此阶段还会构造跟其余类层次相关的数据结构(好比用来实现虚拟方法的动态绑定的方法表),在这个阶段该类没法知道其余类、字段及其方法的地址,所以在须要引用这些成员的时候,java编译器会生成一个符号引用,在运行阶段该引用才可以定位到具体的地址。
  • (3) 解析阶段的目的是将符号引用解析成实际引用,若是符号引用指向一个未被加载的成员,那个将触发JVM对这个类的加载。
    JVM规范并无要求在链接过程当中执行解析工做,它仅仅规定若是某些字段使用了符号引用,那么在执行这些字节码以前须要先完成对这些富豪饮用的解析。

初始化

初始化的目的是为标记为常量的字段赋值,以及执行clinit方法的过程。数组

在初始化一个静态字段的时候,咱们能够再声明时直接赋值,也能够在静态代码块中对其进行赋值。
若是直接赋值的字段被final所修饰,而且字段为基本数据类型和String类型,那么该字段会被编译标记为常量值,其初始化直接由JVM完成。除此以外的全部直接赋值和静态代码块中赋值操做,会被java编译器放到clinit方法中。
数据结构

何时须要对类进行初始化?

(1) 虚拟机启动的时候,初始化用户指定的主类。
(2) 使用new该类实例化对象的时候。
(3) 访问静态字段或静态方法时,初始化静态字段或静态方法所在类。
(4) 子类初始化会触发父类初始化。
(5) 若是接口定义了default方法,那么实现该接口的类初始化会触发该接口的初始化。
(6) 使用反射API的时候。
(7) 当使用JDK1.7的动态语言支持时,若是一个java.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,而且这个方法句柄所对应的类没有进行过初始化,则须要先触发其初始化。code



参考连接:
nomico271.github.io/2017/07/07/…cdn

相关文章
相关标签/搜索