JVM 的类加载过程?

Java 中的类加载过过程分为三个阶段:

  • 加载
  • 链接
    • 验证
    • 准备
    • 解析
  • 初始化

这三个阶段怎么理解?

  • 加载阶段: 查找并加载类的二进制数据(网络、jar 包、运行时生成等)。将类的 .class文件中的二进制数据读入内存当中。将其放在方法区中,然后创建一个java.lang.Class对象(存放于堆中)用于封装类在方法区的数据结构。

  • 链接阶段: Java 类加载器对类进行验证、准备(分配内存、初始化默认值)和解析操作,将类与类之间的关系确定好(符号引用转直接引用),然后校验字节码。

    • 验证:验证文件格式、元数据、字节码、二进制兼容性是否正确
    • 准备:给类的静态变量分配内存,初始化为默认值。
    • 解析:把类的符号引用转为直接引用
  • 初始化阶段: 类加载过程的最后一步,初始化阶段是执行类构造器中<clinit> ()方法的过程。这里利用了一种懒加载的思想,所有 Java 虚拟机实现必须在每个类或者接口被 Java 程序首次主动使用才初始化。

知识扩展

什么是符号引用和直接引用?

符号引用: 是一种直接表示引用目标的符号名称。例如:类名、字段名、方法名等。符号引用和实际的内存地址无关,符号引用只是一个标识符。用于描述被引用者,也就是类似于变量名的东西。符号引用产生于编译期,存储于Class文件。 直接引用: 是实际指向目标的内存地址。例如:类的实例、方法的字节码等。直接引用与内存地址直接相关,产生于运行期。

说白了,符号引用就相当于一个变量名;直接引用就相当于内存地址。