跳到正文
Elaine Blog
返回

JVM 全景:类、内存、线程与执行引擎

JVM 与性能

JVM 不是“运行 Java 的黑盒”。它加载 Class 文件,为线程和对象管理内存,解释或编译字节码,并通过垃圾收集器回收 不可达对象。读完本文,你能把一次方法调用放回这条完整链路,而不是孤立地背诵堆、栈和 GC 名词。

Table of contents

Open Table of contents

从源码到执行结果

一段 Java 代码经历四个主要阶段:

  1. javac.java 源码编译成平台无关的 .class 文件。
  2. 类加载器找到字节并创建 JVM 中的类。
  3. JVM 校验、准备、解析并按需初始化类。
  4. 执行引擎解释字节码,或把热点方法即时编译成当前 CPU 的机器码。

运行实验室中的字节码样例下载

mvn package
java -cp target/classes dev.elaine.jvmlab.BytecodeSample

程序输出 5050。Class 文件没有绑定 macOS 或 Linux 的机器指令;目标机器上的 JVM 决定如何执行它。

四个协作部分

部分主要责任常见证据
类加载子系统找到、校验和初始化类-Xlog:class+load=info
运行时数据区保存对象、栈帧、类元数据等Heap Dump、线程转储、NMT
执行引擎解释字节码并即时编译热点JFR、-XX:+PrintCompilation
垃圾收集器判断对象可达性并回收空间-Xlog:gc*、JFR GC 事件

JVM(Java Virtual Machine)规范规定 Class 文件、指令集和运行时行为;HotSpot 是一个具体实现。对象头大小、JIT 策略和收集器细节多属于实现,不应误写成所有 JVM 都必须遵守的规范。

线程执行方法时发生什么

每个线程拥有自己的 JVM 栈。调用方法时,JVM 创建栈帧(Frame),其中包含局部变量表、操作数栈和动态链接信息。 对象通常位于线程共享的堆中,栈帧只保存基本值或对象引用。

方法里的 new 触发对象分配,但对象不一定永远进入堆。JIT 可能通过逃逸分析消除分配或把字段拆开计算。诊断时应观察 实际分配事件,不要仅凭源码中的 new 推算内存占用。

先观察当前 JVM

运行以下只读命令查看 JVM、堆与系统识别结果:

java --version
java -XshowSettings:vm -version
java -XshowSettings:system -version

-XshowSettings:system 能帮助你确认容器的 CPU 和内存限制是否被识别。具体输出随 JDK、操作系统和容器环境变化, 启动日志应成为部署证据的一部分。

JVM 规范的运行时数据区章节定义了规范边界。 后续文章会逐层验证 HotSpot 的具体行为。

下一步

阅读类加载的双亲委派、隔离与打破方式,理解同名类为什么可能 属于不同类型。


分享这篇文章:

上一篇
从 Java 17 迁移到 21/25
下一篇
类加载的双亲委派、隔离与打破方式