JVM系列3:见证类的诞生与消亡——从加载到卸载的全过程
2023-09-30 12:21:05
生命周期概述:万事开头难
类的生命周期了Java类从加载到使用再到卸载的整个过程。它是一个动态而连续的过程,类会根据程序的需要而创建、使用和销毁。其中,类的卸载会在垃圾回收篇中详细讲解。
如果比较细致的区分,Java类的生命周期可以分成七个阶段:
- 加载(Loading)阶段:JVM将类的字节码文件从文件系统或网络加载到内存中。
- 验证(Verification)阶段:JVM对加载的类字节码文件进行验证,确保它符合Java虚拟机的规范。
- 准备(Preparation)阶段:JVM为类的静态字段分配内存,并设置默认值。
- 解析(Resolution)阶段:JVM将类中的符号引用(如字段、方法、类等)转换为直接引用。
- 初始化(Initialization)阶段:JVM执行类的静态初始化方法,完成类的初始化过程。
- 使用(Using)阶段:应用程序可以使用该类及其成员了。
- 卸载(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运行机制的奥秘,还可以提高开发和调试效率,优化应用程序性能。