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

相关推荐
怎么比啊都是大神36 分钟前
关于==null、isEmpty()和StrUtil.isBlank()
java
唐青枫38 分钟前
Java Neo4j 实战指南:从图模型、Cypher 到 Spring Boot 关系查询
java
观远数据44 分钟前
从离线开发到实时同步:DataFlow如何支撑企业级数据治理闭环
java·windows·microsoft·excel
今天AI了吗2 小时前
Hermes Agent 搭建全流程:从本机试跑到可持续运行的个人 AI Agent
java·人工智能·python·学习·embedding
春卷同学2 小时前
032-关系型数据库在记账应用中的建模与查询优化
java·jvm·数据库
不平衡的叉叉树2 小时前
Springboot+Mockito简单使用单元测试
java·spring boot·单元测试
空中湖2 小时前
Spring AI 多模型接入实战:OpenAI、Ollama、通义千问切换只需改配置
java·人工智能·spring
tianyatest2 小时前
表格分类统计及排序
java·excel·暖通
万亿少女的梦1683 小时前
基于Spring Boot与MySQL的乡镇群众服务系统设计与实现
java·spring boot·mysql·权限管理·前后端分离
thefool1122663 小时前
Java 面向对象
java