S++

千线一眼

导航

JVM-类加载(4)

类加载的三个阶段

加载

将类的字节码加载到方法区中,内部采用 C++ 的 instanceKlass 描述java类
其重要的field有:

  • _super 父类
  • _fields 成员变量
  • _methods 方法
  • _constants 常量池
  • _vtable 虚方法表
  • _itable 接口方法表
  • _class_loader 类加载器
  • _java_mirror java的类镜像

链接

链接阶段又分为三个小阶段:

验证

验证是否符合JVM规范,安全性检查

准备

为static变量分配空间,设置默认值

  • static变量在JDK7之前存储与 instanceKlass 末尾,从JDK7开始,存储于_java_mirror末尾
  • static变量分配空间和赋值是两个步骤,分配空间在准备阶段,赋值在初始化阶段完成
  • 如果static变量是final的基本类型,那么编译阶段值就确定了,赋值在准备阶段完成
  • 如果static变量是final的,但属于引用类型,那么赋值也会在初始化阶段完成

解析

将常量池的符号引用解析为直接引用


初始化

初始化实际上是调用<cinit>()v,虚拟机会保证这个类的构造方法的线程安全。

什么时候会发生初始化

  • main方法所在的类,总是会优先初始化
  • 首次访问这个类的静态变量或静态方法时
  • 子类初始化会联动父类的初始化
  • 子类访问父类的静态变量,只会触发父类初始化
  • 执行Class.forName时
  • new对象时

什么时候不会发生初始化

  • 访问类的静态常量时
  • 类对象.class时
  • 创建该类的数组时
  • 执行类加载器的loadClass方法时
  • Class.forName的第二个参数(是否初始化)为false时

posted on 2022-05-25 20:11  S++  阅读(30)  评论(0编辑  收藏  举报