🔹 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
相关推荐
轮到我狗叫了10 小时前
力扣.84柱状图中最大矩形 力扣.134加油站牛客.abb(hard 动态规划+哈希表)牛客.哈夫曼编码XiaoYu200212 小时前
第1章 核心竞争力和职业规划熬了夜的程序员12 小时前
【LeetCode】99. 恢复二叉搜索树Kent_J_Truman12 小时前
LeetCode Hot100 自用沐怡旸13 小时前
【穿越Effective C++】条款14:在资源管理类中小心copying行为——RAII类的拷贝语义设计1.01^100013 小时前
[5-01-01].第04节:初识字节码文件 - 字节码文件作用沐怡旸13 小时前
【底层机制】ART虚拟机深度解析:Android运行时的架构革命熬了夜的程序员15 小时前
【LeetCode】101. 对称二叉树Kuo-Teng16 小时前
LeetCode 73: Set Matrix Zeroes找不到、了16 小时前
JVM核心知识整理《1》