JVM类加载机制

类加载机制概述:虚拟机把描述类的数据从Class文件加载到内存,并对数据 进行校验、解析、和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制

类的生命周期:7个阶段

其中,验证——准备——解析 称为连接阶段。除了解析外,其他阶段是顺序发生的,而解析可以与这些阶段交叉进行,因为Java支持动态绑定(晚期绑定),需要运行时才能确定具体类型。

 

      其中,验证——准备——解析 称为连接阶段。除了解析外,其他阶段是顺序发生的,而解析可以与这些阶段交叉进行,因为Java支持动态绑定(晚期绑定),需要运行时才能确定具体类型。

         

            在类的加载阶段,加载、验证、准备、初始化是按照顺序严格执行的。但是 Java 虚拟机规范并没有规定什么情况下执行类加载的第一个阶段:加载,这一点可以交给虚拟机的具体实现自由把握。

          可以但是对于初始化阶段,虚拟机规范严格规定: 有且只有 5 种情况 必须立即对类进行初始化(加载、验证、准备自然需要在之前执行),上图已有说明,此处重复介绍:     

          (1) 遇到 new 、getstatic、putstatic 或者 invokestatic 这 4 条字节码指令时,如果没有对类进行初始化,则需要先触发其初始化。这4个指令对应的 Java 场景是:使用 new 新建一个 Java 对象,访问或者设置一个类的静态字段,访问一个类的静态方法的时候。二进制指令参考
          (2)使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行初始化,则需要先触发其初始化。
          (3)当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
          (4)当虚拟机启动的时候,用户需要指定一个需要执行的主类(包含 main 方法的那个类),虚拟机会先初始化这个类。
          (5)当使用 JDK 1.7 的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果 REF_getStatic、REF_putStatic、REF_invokeStatic 的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化。

 

         下面通过一个例子来初步了解下类的加载过程,单例模式中有一个方式是静态内部类来实例化单例,是懒汉式单例(基于双重检查锁和volatile )的变种。

         代码:

public class Singleton {
    private Singleton (){
        System.out.println("外部类实例化");
    }
    static {
        System.out.println("外部类加载");
    }
    private static class SingletonHolder {
        static {
            System.out.println("静态内部类加载");
        }
        private static final Singleton INSTANCE = new Singleton();
    }
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public static void main(String[] args) {
        System.out.println("main方法执行");
        Singleton instance = Singleton.getInstance();
    }
}

         结果:

         根据上面的结果,产生了两个疑问

        1.为什么外部类静态代码块先执行才执行main方法?

        2.为什么调用Singleton.getInstance()才触发Singleton的实例化?

        问题1答案: 当虚拟机启动的时候,用户需要指定一个需要执行的主类(包含 main 方法的那个类),虚拟机会先初始化这个类。初始化阶段类的静态变量赋初始值和执行静态代码块static{   }中的内容,执行的先后顺序取决于在源文件中出现的顺序。

        问题2答案: 触发getstatic后,即访问该类的静态成员变量,这个时候才触发了 Singleton 类的初始化。

 

posted @ 2019-06-17 15:35  Don'tYouSee  阅读(186)  评论(0)    收藏  举报