Tomcat 为什么能部署多个应用?SPI 机制怎么打破双亲委派?热更新怎么实现?类加载是 JVM 的核心机制,也是 Spring、Tomcat、SPI 的底层基础。
一、类加载过程
1.1 七个阶段
加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载
├─────── 连接 ──────────┤
1. 加载(Loading):
通过类全限定名获取字节流(从 jar/class 文件/网络/动态生成)
将字节流转换为方法区的运行时数据结构
在堆中生成 Class 对象,作为方法区数据的入口
2. 验证(Verification):
文件格式验证:魔数 0xCAFEBABE、版本号
元数据验证:语义分析(是否有父类、是否继承 final 类)
字节码验证:方法体逻辑验证(操作数栈、类型转换)
符号引用验证:引用的类/方法/字段是否存在
3. 准备(Preparation):
为类变量(static)分配内存并赋默认值
int → 0, boolean → false, 引用 → null
注意:不是代码中赋的值!
static int x = 123; → 准备阶段 x = 0,初始化阶段 x = 123
特殊:static final(常量)在准备阶段就赋值
static final int x = 123; → 准备阶段 x = 123
4. 解析(Resolution):
将常量池中的符号引用替换为直接引用
符号引用:字符串表示的引用("java/lang/String")
直接引用:内存地址/偏移量
5. 初始化(Initialization):
执行类构造器 <clinit>() 方法
<clinit> = 所有 static 变量赋值 + static 代码块
按代码顺序执行
JVM 保证 <clinit> 线程安全(多线程同时触发初始化时同步)
6. 使用(Using):正常使用
7. 卸载(Unloading):
Class 对象被 GC 回收
条件:该类所有实例被回收 + 加载该类的 ClassLoader 被回收 + Class 对象无引用
2026/7/2大约 9 分钟