JVM 类加载过程笔记

发布于:2025-07-22 ⋅ 阅读:(11) ⋅ 点赞:(0)

一、概述

JVM(Java Virtual Machine)在运行 Java 程序时,需要将 .class 字节码文件加载到内存中,并转换成可以被 JVM 执行的数据结构,这一过程就是 类加载过程(Class Loading Process)

JVM 的类加载机制具备高度灵活性与可扩展性,支持自定义类加载器,且类的生命周期分为以下几个阶段:

二、类的生命周期阶段

  1. 加载(Loading)
  2. 验证(Verification)
  3. 准备(Preparation)
  4. 解析(Resolution)
  5. 初始化(Initialization)
  6. (可选)使用(Using)
  7. (可选)卸载(Unloading)

前五个阶段属于 类加载的过程,使用和卸载属于类的生命周期的后期阶段。


三、类加载的五个阶段详解

1. 加载(Loading)

作用:
.class 文件的字节码从磁盘或网络加载到 JVM 内存中,并生成一个 Class 对象。

步骤:

  • 通过类的全限定名查找 .class 文件。
  • 读取字节流。
  • 将字节流转换成内存中的数据结构。
  • 创建 java.lang.Class 类的实例。

说明:

  • 使用 类加载器(ClassLoader) 完成。
  • 可以自定义类加载器实现特殊的加载逻辑。

2. 验证(Verification)

作用:
确保字节码文件的正确性与安全性,不会破坏 JVM 的稳定性。

主要检查:

  • 文件格式验证(魔数、版本号等)
  • 元数据验证(类结构正确性)
  • 字节码验证(操作码合法性、栈操作正确性)
  • 符号引用验证(类和方法是否存在)

3. 准备(Preparation)

作用:
为类的 静态变量 分配内存,并初始化默认值(不包括静态代码块和显式赋值)。

特点:

  • 所有静态变量初始化为零值(数值为0,对象为null,boolean为false)。
  • 不执行任何 Java 代码。
  • 这一步只是内存分配与默认值初始化。

示例:

public class Demo {
    static int a = 10;
}

在准备阶段,a 的值是 0,真正赋值为 10 的过程发生在 初始化阶段


4. 解析(Resolution)

作用:
将常量池中的 符号引用 转换为 直接引用

解析内容:

  • 类或接口的符号引用 → 直接引用
  • 字段符号引用 → 直接引用
  • 方法符号引用 → 直接引用
  • 接口方法引用 → 直接引用

说明:

  • 并非必须立即解析,可在运行时动态解析(延迟解析)。
  • 也可由 JVM 实现决定是否在加载时解析。

5. 初始化(Initialization)

作用:
执行类构造器 <clinit>() 方法,对静态变量进行显式赋值和执行静态代码块。

执行条件:

  • 创建类的实例
  • 访问类的静态变量或静态方法
  • 反射调用 Class.forName()
  • 初始化类的子类时,其父类会被先初始化
  • JVM 启动时指定的主类(含 main 方法)

注意:

  • 每个类只会初始化一次。
  • 父类先于子类初始化。

四、类加载器(ClassLoader)

类加载器的类型

名称 说明
Bootstrap ClassLoader(启动类加载器) 加载 java.* 核心类库(由 C++ 实现,非 Java 类)
Extension ClassLoader(扩展类加载器) 加载 ext 目录下的类(如 jre/lib/ext
Application ClassLoader(系统类加载器) 加载应用类路径(classpath)下的类
自定义类加载器 用户可以继承 ClassLoader 实现自己的加载逻辑

双亲委派模型(Parent Delegation Model)

工作流程:

  1. 当前类加载器收到加载请求。
  2. 委派给父类加载器。
  3. 父类加载器继续向上委托,直到 Bootstrap ClassLoader。
  4. 若父加载器无法加载,再由当前加载器尝试加载。

优点:

  • 避免类的重复加载。
  • 保证核心类安全性(如 java.lang.String 永远由启动类加载器加载)。

五、类的卸载(Unloading)

条件:

  • 该类的 Class 对象没有任何引用。
  • 加载该类的类加载器没有任何引用。
  • JVM 才能卸载该类。

说明:

  • 卸载的前提是类加载器无引用,通常发生在动态部署的模块或插件系统中。
  • 主动卸载需要结合自定义类加载器。

六、类加载过程图解

              ┌────────────┐
              │ .class 文件 │
              └────┬───────┘
                   ↓
            ┌────────────┐
            │ 加载 Loading│
            └────┬───────┘
                   ↓
         ┌───────────────────┐
         │ 验证 Verification │
         └────┬──────────────┘
                   ↓
          ┌────────────────┐
          │ 准备 Preparation│
          └────┬───────────┘
                   ↓
           ┌──────────────┐
           │ 解析 Resolution│
           └────┬─────────┘
                   ↓
        ┌─────────────────────┐
        │ 初始化 Initialization│
        └─────────────────────┘

网站公告

今日签到

点亮在社区的每一天
去签到