🔹 JVM 类加载的五个阶段(常说三个:加载、链接、初始化)
严格来说有 五个阶段 ,其中 链接 又分为三个子阶段:
1.加载(Loading)
通过类的全限定名(package + className),由类加载器(ClassLoader)查找并加载类的字节码文件(.class)。
常见的类加载器:
Bootstrap ClassLoader (启动类加载器):加载 JDK 核心类库
rt.jar、java.base等。Extension ClassLoader (扩展类加载器):加载
jre/lib/ext或java.ext.dirs目录下的类。Application ClassLoader (应用类加载器):加载
classpath下的类。用户自定义 ClassLoader。
最终将
.class字节流读入内存,在方法区生成对应的 运行时类结构 (Class 对象),并在堆中创建java.lang.Class实例。
2. 链接(Linking)
链接 = 验证 + 准备 + 解析
验证(Verification)
确保字节码文件的正确性与安全性,避免非法操作。
例如:栈数据不会溢出、方法调用合法、类型转换安全。
验证不通过会抛出
VerifyError。
准备(Preparation)
为类的 静态变量(static field) 分配内存,并赋予 默认值(而不是赋程序员写的值)。
例如:
javapublic static int a = 10;在 准备阶段 ,
a的值是 0 (默认 int 值),赋值为 10 会在 初始化阶段执行。
解析(Resolution)
- 将常量池中的符号引用(Symbolic Reference,例如 "java/lang/String")转换为 直接引用(Direct Reference,例如内存地址指针、方法表索引)。
3. 初始化(Initialization)
执行类构造器
<clinit>()方法(由编译器自动收集所有static {}块和静态变量赋值语句组成)。JVM 保证 类初始化是线程安全的 ,即同一个类的
<clinit>()方法在多线程下只会被执行一次。触发类初始化的时机:
使用
new实例化对象调用类的静态方法
访问类的静态变量(非 final 常量)
反射
Class.forName()JVM 启动时加载主类(含
main方法的类)
4. 使用(Using)
类被加载到内存并初始化后,可以被正常使用。
例如:创建对象、调用方法、访问字段。
5. 卸载(Unloading)
类的生命周期结束后,卸载出 JVM。
卸载条件:
该类的所有对象实例都已被回收。
该类的 ClassLoader 已被回收。
对应的
java.lang.Class对象不再被引用。一般只在 自定义类加载器 + 动态加载/卸载类(如 Tomcat 热部署、OSGi 框架) 时常见。
🔹 类加载的双亲委派机制
当一个类加载器收到类加载请求时,不会自己去加载,而是先委托给父类加载器。
如果父类加载器无法完成(找不到该类),才由子类加载器尝试加载。
优点:
避免重复加载类。
保证核心类库的安全(用户自定义的
java.lang.String不会覆盖 JDK 自带的 String)。
🔹 总结(流程图式)
java类加载过程: 加载 → 链接(验证 → 准备 → 解析) → 初始化 → 使用 → 卸载
面试tips--JVM(3)--类加载过程
你我约定有三2025-08-29 12:03
相关推荐
kyriewen1 分钟前
我把今年流传的前端 AI 面试题整理了一遍——4 类场景题+回答框架(附速查表)AEI2 小时前
四年间大模型的演进历程学习星球6 小时前
OFDM技术精讲:正交性推导、循环前缀原理与80行Python链路仿真(附实测数据)YIAN10 小时前
Docker + Nginx 核心原理扫盲:从环境隔离到反向代理,运维面试必考点蒸蒸yyyyzwd12 小时前
cpp 选手秋招学习笔记 day21黄敬峰12 小时前
一文搞懂宝塔面板部署前后端分离项目(React + Node.js + MySQL)Interview Aid11212 小时前
TikTok OA 四题分享|半小时内 AC,题目基本都是实现题怕浪猫20 小时前
FDE 最大的浪费不是写出有 bug 的代码,而是漂亮地解决了一个错误的问题黄敬峰1 天前
Next.js 全栈实战:数据清洗、ORM 设计与 AI Prompt 工程最佳实践wuminyu1 天前
深入剖析 Panama Off-heap 的性能损耗与开销