从“类加载的五个阶段”逐步分析 JVM“ 在每个阶段的内存变化”

下面从 类加载的五个阶段 逐步分析 JVM 在每个阶段的内存变化 。

(以 HotSpot + Java17 为例,Java8 以后方法区已改为 Metaspace)


JVM 相关内存区域速览

区域 作用 是否线程共享
堆(Heap) 对象实例、数组 共享
方法区 / 元空间 (Metaspace) 类的元信息、静态变量、常量池、JIT 代码 共享
运行时常量池 字面量、符号引用 共享
栈 (Java Stack) 局部变量、操作数栈、方法帧 线程私有
程序计数器 当前字节码行号 线程私有

类加载生命周期与内存变化

1️⃣ 加载 (Loading)

做的事

  • 通过 ClassLoader 读取 .class 字节码,形成 Class 对象。

内存变化

  • Metaspace:分配空间存放类的结构信息(字段、方法表、字节码指令)。
  • 运行时常量池:复制 class 文件中的常量池(符号引用、字符串字面量等)。
  • 堆/栈:暂时无变化。

2️⃣ 验证 (Verification)

做的事

  • 校验字节码格式、安全性(魔数、常量池索引、数据流、控制流)。

内存变化

  • Metaspace 中的类结构已存在,只进行一致性检查,没有额外分配大量内存。

3️⃣ 准备 (Preparation)

做的事

  • 为类的静态变量分配内存并设默认值(int=0、reference=null 等)。

内存变化

  • Metaspace:

    • 分配静态变量所需空间,存储在类元数据区域。
    • 如果是 static final 且编译期常量,值直接存入运行时常量池。
  • 堆:此时不会创建对象实例。


4️⃣ 解析 (Resolution)

做的事

  • 把运行时常量池中的符号引用解析成直接引用(内存地址或句柄)。

内存变化

  • 运行时常量池中保存的直接引用指针被填充。
  • 可能触发其他类的加载/初始化,间接扩展 Metaspace 占用。

5️⃣ 初始化 (Initialization)

做的事

  • 执行 <clinit>:静态变量显式赋值、静态代码块。

内存变化

  • Metaspace:静态变量值被正式写入。

  • 堆:

    • 如果静态变量是对象或集合,此时会在堆上创建对象实例并把引用放到 Metaspace 静态变量表。
  • 栈 :执行 <clinit> 方法帧入栈,执行完后出栈。


运行时继续变化

  • 实例化对象 → 在堆上分配实例内存。
  • 类卸载(ClassLoader 不再被引用)→ 其在 Metaspace 中的元数据、静态变量会被 GC 回收。

简化时序图

复制代码
Class 文件
   │
   ▼
[加载] ──► Metaspace: 类结构、常量池
   │
[验证] ──► 仅检查,无大变化
   │
[准备] ──► Metaspace: 静态变量默认值
   │
[解析] ──► 常量池符号引用 → 直接引用
   │
[初始化] ──► Metaspace: 赋真实值
   │          Heap: 静态对象实例

小结

  • 类元信息 + 静态变量存放在 Metaspace
  • 实例对象在 Heap
  • 执行方法时用栈
  • 类加载阶段的内存主要变化是 Metaspace 的增长 ,初始化阶段可能会触发 Heap 分配。
相关推荐
金銀銅鐵11 小时前
[Java] 借助GUI展示class文件的内容(v1.0版本)
jvm·后端·ai编程
kunicoding12 小时前
多线程编程核心概念详解:从线程基础到并发安全
java·jvm·安全
云老大-阿里云国际站代理商18 小时前
华为云国际站渠道代理商:CSS查询很慢但CPU不高?磁盘I/O、JVM与分片问题怎么排查
css·jvm·华为云
呆呆虫1219 小时前
SerpBase 省 credit 实战:缓存 + 去重,把重复请求砍掉一半
jvm·缓存
戴西软件1 天前
企业如何搭建自己的AI智能体?戴西智能体管理与戴西SKILL管理实战解析
运维·jvm·人工智能·自动化·rpa
小张成长计划..2 天前
【Linux】25:线程概念和控制
java·linux·jvm
用户094248568033 天前
第38章:从零构建JVM稳定性平台最小闭环
java·jvm
Java成神之路-3 天前
深入理解 G1 Mixed GC:触发条件、完整流程与高频误区
jvm·g1垃圾回收算法
认真的小羽❅3 天前
ThreadLocal 在虚拟线程间要小心
java·开发语言·jvm
今天的砖头有点烫手啊3 天前
Java 8 Stream 原理拆解:惰性求值与并行流陷阱
java·jvm