JVM类加载机制(一)

一、概念

  程序编译后,生成class文件,经过加载、验证、准备、解析、初始化,最终使程序可以被JVM识别。

二、类的生命周期

  类从被加载到虚拟机内存开始,到卸载出虚拟机内存结束,一共经历加载、验证、准备、解析、初始化、使用、卸载七个阶段。

其中验证、准备、解析统称为连接。

  借用网上的图:

  其中解析过程在某些情况下可以在初始化之后执行,这是为了支持JAVA的动态绑定。

三、类的初始化时机

  1. 使用new实例化对象

  2. 反射

  3. 初始化一个类时,发现父类没有被初始化,先初始化父类

  4. 指定要执行的主类包含main方法

  5. 使用JDK1.7的动态语言支持时,MethodHandle实例包含REF_getputinvoke static句柄,且对应类未初始化

  以上场景行为称为对类的主动引用,而被动引用不会被初始化,包含以下几个场景:

  1. System.out.print(SubClass.value); // value的引用在父类SuperClass中

  2. SuperClass[] sca =new SuperClass[10]; // 数组类型不会触发类的初始化

    数组类型是jvm自动生成、继承Object的子类。

  3.System.out.print(Constants.HELLOWORLD); // 常量类在编译时将进入常量池,本质上不会调用Constants类的初始化。

四、类加载过程

  1. 加载

  • 根据(包名+类名)获取该类的二进制流
  • 将二进制流的静态存储结构转化为方法区的运行时存储结构
  • 生成 java.lang.Class对象,并作为该类的唯一入口

  2. 验证

  • 文件格式验证:是否以0xCAFEBABE开头、class文件版本号等
  • 元数据验证:语义分析,保证描述的信息符合java规范,这一步并未涉及方法体内
  • 字节码验证:方法体内部代码是否合法、符合逻辑
  • 符号引用验证:是否能定位到类,验证字段、类、接口方法的访问权限

  3. 准备

  static修饰的变量将被设置为零值。

  

   public static int value = 123; // 在准备阶段将被赋0

   public static final int value = 123; // 如果是常量,将直接初始化,而不是0,因为final的意思是:不可变的。

  4. 解析

  符号引用->直接引用

  5. 初始化

  初始化阶段才开始真正的执行JAVA代码,该阶段是虚拟机执行类构造器<clinit>()方法的过程。

  <clinit>()方法有以下特点:

  • 按语义顺序收集类变量的赋值动作和静态语句块static{ },其中静态语句块只能访问在它之前定义的变量,在它之后的只能赋值。

  

public class Test {
    static {
        i = 0;                // 给变量赋值可以正常编译通过
        System.out.print(i);  // 这句编译器会提示“非法向前引用”
    }
    static int i = 1;
}
  • 保证子类的<clinit>()方法在执行之前,父类的<clinit>()已经执行完成。
static class Parent {
    public static int A = 1;
    static {
        A = 2;
    }
}
 
static class Sub extends Parent {
    public static int B = A;
}
 
public static void main(String[] args) {
     System.out.println(Sub.B);  // 输出结果是父类中的静态变量 A 的值,也就是 2。
}
  • <clinit>()对于接口或类不是必须的,如果一个类没有对类变量的赋值动作,且无静态方法块static{},编译器可以

不为该类生成<clinit>()方法。

  • 接口有变量赋值动作时,执行<clinit>()不会执行父类的<clinit>(),实现该接口的类初始化时不会执行接口的<clinit>方法
  • 多线程下,jvm保证类的<clinit>被正确的加锁和同步,多个线程同时初始化类构造器,将只有一个类初始化,其他将

阻塞,所以<clinit>有耗时操作时将会造成线程阻塞。

每一步脚印都要扎得深一点!
原文地址:https://www.cnblogs.com/bloodthirsty/p/12502799.html