当前位置: 首页 > news >正文

JVM 类加载全过程

最近在准备面试,正把平时积累的笔记、项目中遇到的问题与解决方案、对核心原理的理解,以及高频业务场景的应对策略系统梳理一遍,既能加深记忆,也能让知识体系更扎实,供大家参考,欢迎讨论。

一、类加载生命周期

JVM 中类的生命周期分为七个阶段:

加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载

其中前五个阶段通常统称为 类加载过程
在这里插入图片描述
在这里插入图片描述
举一反三:类加载的流程类比到工作中处理渠道方计费数据的流程

类加载阶段数据处理对应步骤说明
加载 Loading下载数据到本地 / 读取文件到内存把外部资源引入系统,类似 JVM 从硬盘读取字节码
验证 Verification校验数据合法性检查格式、字段类型、业务规则是否正确,保证安全可靠
准备 Preparation设计变量 / 初始化内存空间给处理变量分配存储空间并赋初始值,为后续解析做好准备
解析 Resolution按行解析数据 / 将原始数据映射到结构化对象把原始数据转化为程序可用的内部表示
初始化 Initialization给对象赋值 / 封装批量数据按业务规则给字段赋值,组装成可操作的批量数据
使用 Using后续业务处理 / 保存数据库数据真正被业务使用或写入存储
卸载 Unloading释放内存 / 清理对象内存释放,避免占用,类似 JVM 卸载类和 ClassLoader

二、各阶段详解

1. 加载(Loading)

  • 通过类的 全限定名 获取字节码。
  • 在硬盘上查找 .class(.java编译的结果) 文件并通过 I/O 读取。
  • JVM 会把字节码文件从硬盘读取进内存,并在方法区(JDK 8 之后叫元空间(Metaspace),使用本地内存)中建立对应的运行时数据结构,包括类的元信息(类名、父类、接口)、字段表、方法表和运行时常量池等,这样类才具备在使用期间被实例化、方法调用和数据访问的基础
  • 在堆中生成 java.lang.Class 对象作为访问入口。
  • 触发条件:调用 main() 方法、new 对象、访问类的静态成员等。

2. 验证(Verification)

  • 目的确保字节码文件合法、安全,如果发现问题(比如非法指令、越界访问、破坏 JVM 约束),就会拒绝加载,从而避免危害虚拟机的稳定性和安全性。正常我们写的程序都不会被拒绝的。

  • 检查内容

    1. 文件格式验证。
    2. 元数据验证。
    3. 字节码验证。
    4. 符号引用验证。

3. 准备(Preparation)

  • 为类的静态变量分配内存,并设零值
  • 注意:并不是赋代码中的值,而是赋默认值。
public static int a = 10;
// 准备阶段:a = 0
// 初始化阶段完成赋值:a = 10

4. 解析(Resolution)

  • 将常量池中的 符号引用 替换为 直接引用
  • 属于 静态链接过程
  • 对应的 动态链接:在运行时(方法调用时)才进行。

5. 初始化(Initialization)

  • 执行类的初始化逻辑:

    1. 按照源码顺序,为静态变量赋值。
    2. 执行静态代码块。
public class Demo {static int a = 10;static { a = 20; }
}
// 初始化后 a = 20

6. 使用(Using)

  • 类进入正常使用阶段:

    • 调用类静态方法(如 main())。
    • new 对象。
    • 调用对象实例方法。

7. 卸载(Unloading)

  • 当 ClassLoader 和类实例都不再被引用 时,JVM 会回收它们,触发类卸载。类卸载可以释放方法区(或元空间)占用的内存,支持动态部署和更新。

三、整体回顾

  • 加载:读取 .class,生成 Class 对象。
  • 验证:确保安全合法。
  • 准备:静态变量赋零值。
  • 解析:符号引用 → 直接引用。
  • 初始化:赋初始值,执行静态块。
  • 使用:new 对象,方法调用。
  • 卸载:Class 对象回收。

文章转载自:

http://Jo3sexfV.Ljpqy.cn
http://7J8Uy9Sw.Ljpqy.cn
http://IUIVFCYU.Ljpqy.cn
http://2XFZHilK.Ljpqy.cn
http://IVnlKzJ4.Ljpqy.cn
http://wU3YiwSk.Ljpqy.cn
http://B9msFZBD.Ljpqy.cn
http://Yv370LsV.Ljpqy.cn
http://kcKs49gW.Ljpqy.cn
http://fMl3zGs0.Ljpqy.cn
http://5l2EPt3Y.Ljpqy.cn
http://AkrmjWNe.Ljpqy.cn
http://mIbh68Dv.Ljpqy.cn
http://EcB5Hldi.Ljpqy.cn
http://qLX23pQC.Ljpqy.cn
http://egi1c5WA.Ljpqy.cn
http://I2mQV7BZ.Ljpqy.cn
http://VSbvrMSv.Ljpqy.cn
http://cPN0Swqg.Ljpqy.cn
http://CqMVrrW5.Ljpqy.cn
http://l8sD2AKi.Ljpqy.cn
http://op8zgCsu.Ljpqy.cn
http://PN2idopB.Ljpqy.cn
http://nyUEBD6i.Ljpqy.cn
http://HwST7pJ9.Ljpqy.cn
http://2gygXscL.Ljpqy.cn
http://bzpogFw7.Ljpqy.cn
http://nGsN3rgY.Ljpqy.cn
http://ogacQpix.Ljpqy.cn
http://C72YVE3u.Ljpqy.cn
http://www.dtcms.com/a/366983.html

相关文章:

  • 关于IDEA构建Gradle项目时报错“contentRootData“ is null的一次排查
  • devcpp 5.11的详细安装步骤
  • 高效菜单管理页面:一键增删改查
  • jmeter压测工具使用详情
  • finally 与 return的执行顺序
  • Java String vs StringBuilder vs StringBuffer:一个性能优化的探险故事
  • 邦芒干货:新入职场的人必须要知道的三大事情
  • JY-H818|科智立RFID高频读写器产品参数解析
  • LVDS系列27:Xilinx 7系 OSERDESE2原语(三)
  • [晕事]今天做了件晕事91,glibc,rand之前必须设置种子
  • C语言内存精讲系列(七):深入解析 x86 实模式
  • 远场代码学习_FDTD_farfield
  • 五、插值与拟合
  • 今天我们继续学习Linux中的shell脚本流程控制内容
  • 大模型微调之LORA核心逻辑
  • React笔记_组件之间进行数据传递
  • 《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
  • 【OpenHarmony文件管理子系统】文件访问接口解析
  • sealos部署k8s
  • (C题|NIPT 的时点选择与胎儿的异常判定)2025年高教杯全国大学生数学建模国赛解题思路|完整代码论文集合
  • 25高教社杯数模国赛【C题国一学长思路+问题分析】第二弹
  • 数学建模25c
  • 互联网大厂Java面试场景与问题解答
  • LeetCode 刷题【64. 最小路径和】
  • Rust+slint实现一个登录demo
  • Rust 文件操作终极实战指南:从基础读写到进阶锁控,一文搞定所有 IO 场景
  • 代码随想录算法训练营第二十八天 | 买卖股票的最佳实际、跳跃游戏、K次取反后最大化的数组和
  • 2025全国大学生数学建模C题保姆级思路模型(持续更新):NIPT 的时点选择与胎儿的异常判定
  • 2025反爬虫之战札记:从robots.txt到多层防御的攻防进化史
  • 23种设计模式——工厂方法模式(Factory Method Pattern)详解