类加载机制

  • 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行一系列处理,形成可以被虚拟机直接使用的Java类型,称为虚拟机的类加载机制

类的加载过程

JVM加载一个类共分为3个步骤:加载,链接,初始化。其中链接又分为3个步骤:验证,准备,解析
JVM(三-一)类加载机制

  1. 加载
    共分为3步:1)获取定义此类的二进制字节流;2)将字节流代表的静态存储结构转化为方法区的运行时数据结构;3)在堆中实例化一个这个类的Class对象,作为方法区这个类的入口。
    其实加载阶段用一句话来说就是:把代码数据加载到内存中
    JVM(三-一)类加载机制
  2. 链接
    (1)验证
    主要是确认字节流包含的信息符合虚拟机的要求,不含有害信息危害虚拟机安全,主要有4个阶段:文件格式验证,元数据验证,字节码验证,符号引用验证。
    (2)准备
    为类中的静态变量赋初始值(零值),但如果是静态常量(即被final修饰),在准备阶段直接就它设置为真正的初始值了。
    注:Java 中的变量有「类变量」和「类成员变量」两种类型,「类变量」指的是被 static修饰的变量,而其他所有类型的变量都属于「类成员变量」。在准备阶段,JVM只会为「类变量」分配内存,而不会为「类成员变量」分配内存。「类成员变量」的内存分配需要等到初始化阶段才开始。
    (3)解析
    将常量池中的符号引用替换成直接其在内存中的直接引用。
  3. 初始化
    到了初始化阶段,用户定义的 Java 程序代码才真正开始执行,即虚拟机执行类构造器 < clinit >() 方法的过程。一般来说当 JVM 遇到下面 5 种情况的时候会触发初始化:
    (1)遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象的时候、读取或设置一个类的静态字段(被final修饰、已在编译器把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
    (2)使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
    (3)当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
    (4)当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。
    (5)当使用 JDK1.7 动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果 REF_getstatic ,REF_putstatic ,REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化。

https://blog.csdn.net/qq_22938671/article/details/89926724
https://mp.weixin.qq.com/s/YTa0h4FSjqvbKDuGYjHjHw

相关文章: