JVM-类加载过程

类加载过程是 Java 虚拟机 (JVM) 将 Java 代码编译后的字节码文件加载到内存中,并进行解析和验证,最终使程序能够运行的关键步骤。

  • 类加载过程:加载->连接->初始化
  • 连接过程又可分为三步:验证->准备->解析

1. 加载(Loading)

将字节码文件读入内存,并将其转换为 JVM 能够识别的 Class 对象。

这个过程通常涉及以下几个步骤:

  • 查找:JVM根据类的全名(包括包名)查找相应的字节码文件(.class文件)。这可以从本地文件系统、网络或其他资源中获取。
  • 读取:找到字节码文件后,JVM会将其读取到内存中。
  • 解析:将字节码中的符号引用(如类名、方法名、字段名等)转换为直接引用。这一过程通常在后续步骤中进行。

2.验证 (Verification)

检查字节码文件的合法性和安全性,确保其符合 JVM 规范,防止恶意代码攻击。

  • 文件格式验证:检查字节码文件的格式是否正确。
  • 字节码验证:确保字节码符合Java语言的语法和语义规则,例如,确保方法的调用和字段的访问是合法的。
  • 类型验证:检查类的继承关系和类型兼容性,确保类型安全。

3. 准备(Preparation)

在准备阶段,JVM会为类的静态变量分配内存,并将其初始化为默认值 (如0、null等)。此时,类的静态变量会被分配到方法区(Method Area)。

4. 解析(Resolution)

解析(Resolution)是将符号引用转换为直接引用的过程。

主要是将字节码中的符号引用(如类名、方法名和字段名)转换为在内存中实际指向 这些元素的地址 。这一过程确保了在运行时能够正确地访问和调用类、方法和字段。

符号引用和直接引用

  • 符号引用
    • 符号引用是指在字节码中以字符串形式表示的类、方法或字段的名称。
    • 例如,类B的符号引用可能是字符串"B",而方法display的符号引用可能是字符串"display"。
  • 直接引用
    • 直接引用是指在内存中实际的地址或指针,指向类、方法或字段的具体实现。直接引用允许JVM快速访问这些元素,而无需再次查找。

示例

java 复制代码
class A {
    void methodB() {
        B b = new B();  // 这里需要解析B类
        b.display();    // 这里需要解析display方法
    }
}

class B {
    void display() {
        System.out.println("Hello from B");
    }
}
  • methodB被调用时,JVM首先会解析类B,找到它在内存中的地址。
  • 然后,在调用b.display()时,JVM会解析display方法,找到该方法在内存中的地址。

5. 初始化(Initialization)

初始化阶段是类加载过程的最后一步。在这一阶段,JVM会执行类的初始化代码,包括静态变量的初始化和静态代码块的执行。初始化过程遵循以下规则:

  • 静态变量初始化:根据在类中定义的顺序,初始化所有静态变量。
  • 静态代码块执行:执行类中的所有静态代码块。

6. 使用(Using)

类加载完成后,JVM可以使用该类进行实例化、方法调用等操作。此时,类的生命周期开始,JVM可以根据需要创建类的实例并调用其方法。

7. 卸载(Unloading)

在某些情况下,当类不再被使用时,JVM会将其从内存中卸载。卸载过程通常由垃圾回收机制管理,以释放内存资源。

卸载类需要满足 3 个要求:

  1. 该类的所有的实例对象都已被 GC,也就是说堆不存在该类的实例对象。
  2. 该类没有在其他任何地方被引用
  3. 该类的类加载器的实例已被 GC

所以,在 JVM 生命周期内,由 jvm 自带的类加载器加载的类是不会被卸载的。但是由我们自定义的类加载器加载的类是可能被卸载的。

参考:类加载过程详解 | JavaGuide

相关推荐
苦瓜小生11 分钟前
【前端】|【js手撕】经典高频面试题:手写实现function.call、apply、bind
java·前端·javascript
NGC_66111 小时前
Java 线程池:execute () 和 submit () 到底有什么区别?
java
cngm1101 小时前
解决麒麟v10下tomcat无法自动启动的问题
java·tomcat
色空大师1 小时前
【网站搭建实操(一)环境部署】
java·linux·数据库·mysql·网站搭建
客卿1231 小时前
牛客刷题--找数字-- 字符串检测-字符串 双指针
java·开发语言
烛之武1 小时前
SpringBoot基础
java·spring boot·后端
IAUTOMOBILE1 小时前
用Python批量处理Excel和CSV文件
jvm·数据库·python
Amour恋空2 小时前
Java多线程
java·开发语言·python
小胖java2 小时前
高校培养方案制定系统
java·spring
常利兵2 小时前
Spring项目新姿势:Lambda封装Service调用,告别繁琐注入!
java·数据库·spring