一、类的生命周期
类的生命周期描述了一个类加载、连接、初始化、使用、卸载的整个过程。
1.加载(Loading)
加载阶段是类的生命周期的起始点。当应用程序首次需要使用某个类时,Java虚拟机(JVM)会负责加载这个类。加载是通过类的加载器(ClassLoader)完成的,它会查找并加载类的二进制数据。这个过程包括将类的字节码从文件系统、JAR文件或网络加载到内存中。
2.连接(Linking)
连接阶段是加载阶段的后续,它包括验证、准备和解析三个子阶段。
- 验证(Verification):验证阶段主要是确保被加载的类文件数据符合JVM规范,没有安全方面的隐患,以及是否与应用程序的其它部分兼容。验证过程包括文件格式验证、元数据验证、字节码验证和符号引用验证。
- 准备(Preparation):准备阶段是为类的静态变量分配内存,并设置默认的初始值。需要注意的是,准备阶段并不会执行任何初始化操作。
- 解析(Resolution):解析阶段是将符号引用转换为直接引用。在Java中,符号引用是一个类的全限定名,而直接引用是一个直接指向内存中的地址的指针。解析阶段发生在运行时,而不是编译时。
3.初始化(Initialization)
初始化阶段是类加载过程中的最后一步,当准备和解析阶段完成后,JVM会执行类的构造器方法,这个方法是由编译器自动收集类中的所有类变量的赋值动作和静态代码块集合来的。需要注意的是,构造器方法中的代码只在类被首次使用时执行一次。
4.使用(Using)
一旦类被成功加载、连接并初始化后,就可以被实例化并用于执行应用程序的业务逻辑。在应用程序运行期间,类可能会被频繁地使用。
5.卸载(Unloading)
当应用程序不再需要某个类时,该类的实例以及与其相关的资源将会被回收,这个过程就是卸载。但是需要注意的是,只有当一个类不再被任何活动对象所引用时,它才会被卸载。另外,JVM的垃圾回收机制(Garbage Collection, GC)负责自动处理类的卸载和资源的回收。
二、加载阶段
加载(Loading)阶段是类生命周期的起始点,它涉及将类的二进制数据从文件系统或其他来源加载到Java虚拟机中。这个过程主要由类加载器完成,它根据类的全限定名获取字节码信息。类加载器可以通过多种方式获取字节码信息,包括从JAR文件、ZIP文件、网络或其他自定义源中读取。
加载阶段根据类的全限定名把字节码文件的内容加载并转换成合适的数据放入内存中,存放在方法区和堆上。在加载阶段,类加载器首先会检查类是否已经被加载过。如果已经加载过,则直接返回已加载的类信息,否则,它会进行以下操作:
- 通过类的全限定名获取类的二进制数据(字节码)。
- 将字节码信息转换为方法区的内部表示。方法区是Java虚拟机的一个内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量等数据。在这个阶段,Java虚拟机会为每个加载的类生成一个InstanceKlass对象,该对象包含了类的所有信息,包括类的实现细节,例如多态的实现。
- 在堆中创建一个java.lang.Class对象。这个对象的作用是提供一种在Java代码中访问类的信息的方式,以及存储静态字段的数据(从JDK8开始)。开发者通常只需要通过这个Class对象来访问类的信息,而不需要直接访问方法区中的所有数据。这种设计使得Java虚拟机能够更好地控制开发者对数据的访问范围,增强了安全性。
通过上述过程,类的加载阶段完成了类的二进制数据的读取和解析,并将其存储在Java虚拟机的内存中,为后续的连接和初始化阶段做好了准备。这个过程对于任何在Java虚拟机上运行的程序都是必不可少的,因为它是类能够被执行的前置条件。
总结
JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了类的生命周期、类的加载阶段等内容,希望对大家有所帮助。