类加载

类加载

类的生命周期( 7 个阶段)

  • 加载(Loading)
  • 验证(Verification)
  • 准备(Preparation)
  • 解析(Resolution)
  • 初始化(Initialization)
  • 使用(Using)
  • 卸载(Unloading)

加载(Loading)

加载阶段,虚拟机需要完成以下三件事情:

1、通过一个类的全限定名来获取定义此类的二进制字节流。

2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

3、在 Java 堆中生成一个代表这个类的 java.lang.Class 对象,作为方法区这些数据的访问入口。

验证(Verification)

  • 文件格式验证
  • 元数据验证
  • 字节码验证
  • 符号引用验证

准备(Preparation)

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。

这时候进行内存分配的仅包括类变量(被 static 修饰的变量),而不包括实例变量,实例变量将会在对象初始化时随着对象一起分配在 Java 堆中。

解析(Resolution)

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,符号引用在 Class 文件中以 CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info 等类型的常量出现。

  • 符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义的定位到目标即刻。符号引用于虚拟机实现的内存布局无关,引用的目标并不一定已经加载到内存中。
  • 直接引用(Direct References):直接引用可以是直接指向目标的指针、相对便宜量或是一个能间接定位到目标的句柄。直接引用是与虚拟机实现的内存布局相关的,同一个符号引用在不同虚拟机示例上翻译出来的直接引用一般不会想用。如果有了直接引用,那引用的目标必定已经在内存中存在。

1、类或接口的解析

2、字段解析

3、类方法解析

4、接口方法解析

初始化(Initialization)

此阶段是类加载过程的最后一步。