返回

JVM系列3:见证类的诞生与消亡——从加载到卸载的全过程

后端

生命周期概述:万事开头难

类的生命周期了Java类从加载到使用再到卸载的整个过程。它是一个动态而连续的过程,类会根据程序的需要而创建、使用和销毁。其中,类的卸载会在垃圾回收篇中详细讲解。

如果比较细致的区分,Java类的生命周期可以分成七个阶段:

  1. 加载(Loading)阶段:JVM将类的字节码文件从文件系统或网络加载到内存中。
  2. 验证(Verification)阶段:JVM对加载的类字节码文件进行验证,确保它符合Java虚拟机的规范。
  3. 准备(Preparation)阶段:JVM为类的静态字段分配内存,并设置默认值。
  4. 解析(Resolution)阶段:JVM将类中的符号引用(如字段、方法、类等)转换为直接引用。
  5. 初始化(Initialization)阶段:JVM执行类的静态初始化方法,完成类的初始化过程。
  6. 使用(Using)阶段:应用程序可以使用该类及其成员了。
  7. 卸载(Unloading)阶段:当类不再被使用时,JVM会将其从内存中卸载。

加载阶段:踏入Java世界的第一步

类加载阶段是类生命周期的第一步。它由JVM根据需要将类的字节码文件从文件系统或网络加载到内存中。类加载器负责执行类加载任务,它可以是启动类加载器、扩展类加载器或用户自定义的类加载器。

当一个类被加载时,JVM会首先检查它是否已经被加载过。如果已经被加载,则直接返回已加载的类。否则,JVM会根据类的完整限定名来查找它的字节码文件。字节码文件通常存储在JAR文件或其他类型的归档文件中。

字节码文件加载到内存后,JVM会对它进行验证,确保它符合Java虚拟机的规范。验证过程包括验证字节码文件的格式、语法和语义。如果验证失败,JVM会抛出VerifyError异常。

验证阶段:确保字节码的合法性

验证阶段是类生命周期的第二步。在加载阶段,JVM已经将类的字节码文件加载到内存中。现在,JVM需要验证字节码文件是否符合Java虚拟机的规范。验证过程包括:

  • 检查字节码文件的格式是否正确。
  • 检查字节码文件的语法是否正确。
  • 检查字节码文件的语义是否正确。

如果验证失败,JVM会抛出VerifyError异常。VerifyError异常是一个运行时异常,它表示字节码文件不符合Java虚拟机的规范。

准备阶段:为静态字段分配内存

准备阶段是类生命周期的第三步。在验证阶段,JVM已经验证了类的字节码文件是否符合Java虚拟机的规范。现在,JVM需要为类的静态字段分配内存,并设置默认值。

静态字段是类级别的字段,它属于整个类,而不是某个特定的对象。静态字段在类加载时被初始化,并且在整个程序运行过程中保持不变。

解析阶段:将符号引用转换为直接引用

解析阶段是类生命周期的第四步。在准备阶段,JVM已经为类的静态字段分配了内存,并设置了默认值。现在,JVM需要将类中的符号引用(如字段、方法、类等)转换为直接引用。

符号引用是相对于其他类的引用,它使用类的名称或字段的名称来引用类或字段。直接引用是相对于内存地址的引用,它使用内存地址来引用类或字段。

解析过程包括将类中的符号引用转换为直接引用。解析过程是递归的,它会一直持续到所有的符号引用都被转换为直接引用为止。

初始化阶段:执行静态初始化方法

初始化阶段是类生命周期的第五步。在解析阶段,JVM已经将类中的符号引用转换为直接引用。现在,JVM需要执行类的静态初始化方法,完成类的初始化过程。

静态初始化方法是类级别的初始化方法,它属于整个类,而不是某个特定的对象。静态初始化方法在类加载时被执行,并且在整个程序运行过程中只被执行一次。

静态初始化方法可以用来初始化静态字段、注册事件监听器或执行其他初始化操作。

使用阶段:类的闪耀时刻

使用阶段是类生命周期的第六步。在初始化阶段,JVM已经执行了类的静态初始化方法,完成了类的初始化过程。现在,应用程序可以使用该类及其成员了。

应用程序可以通过以下方式使用类:

  • 创建类的实例。
  • 调用类的静态方法。
  • 访问类的静态字段。

卸载阶段:功成身退,卸下重担

卸载阶段是类生命周期的第七步。当类不再被使用时,JVM会将其从内存中卸载。卸载过程包括:

  • 卸载类的字节码文件。
  • 释放类占用的内存。
  • 撤销类的注册信息。

卸载阶段通常在应用程序退出时执行。但是,在某些情况下,JVM可能会在应用程序运行期间卸载类。例如,当类所在的JAR文件被删除或重命名时,JVM可能会卸载该类。

类生命周期是一个动态而连续的过程,类会根据程序的需要而创建、使用和销毁。通过对类生命周期的深入理解,我们不仅可以揭开Java运行机制的奥秘,还可以提高开发和调试效率,优化应用程序性能。