JVM

Java Fundamentals

编译器 × 虚拟机

编译器负责“翻译”,虚拟机负责“执行”。从 javac 到 JVM,看一段 Java 代码如何跑起来。

javac .java → .class
字节码 Bytecode
JVM .class → 机器码

纵向滚动 · 悬停可查看详情

FLOW

Step by Step

代码的完整旅程

悬停每个环节,看看它在这一步做了什么。

源代码Hello.java
程序员编写的人类可读代码,包含类、方法、变量等结构,计算机还无法直接执行。
→
编译器 javac编译期
做语法检查和类型检查,把源码翻译成平台无关的字节码,输出 .class 文件。
→
字节码Hello.class
一种中间格式,不针对任何操作系统。任何平台上安装了 JVM 就能读懂它。
→
JVM 虚拟机运行期
加载类、管理内存,把字节码解释执行,热点代码则由 JIT 编译器转成机器码。
→
机器码操作系统执行
最终由操作系统和 CPU 直接执行的指令,程序在这一步真正跑起来。

悬停任意环节即可浮现详情,移开后自动收起。

03

Division of Labor

各司其职

从两个角色各自的视角看一遍,再悬停行查看协作关系。

🧊 编译器 javac→

在程序运行之前工作,只做一次:输入 Hello.java,检查语法与类型错误,输出与操作系统无关的 Hello.class 字节码。它不关心你最终在哪个平台上运行。

⚙️ 虚拟机 JVM→

在程序运行时工作:加载 Hello.class,用类加载器验证字节码并解释执行;发现热点代码时,由 JIT 编译器直接编译成机器码并缓存,同时负责内存管理与垃圾回收。

🤝 协作关系→

javac 负责“统一”,JVM 负责“落地”:javac 生成平台无关的字节码,各平台安装各自的 JVM 来解读同一份字节码,因此代码只需编译一次,就能在 Windows、macOS、Linux 上运行。

04

Why Two Stages

为什么需要“分工”?

如果编译器直接生成机器码,同一份代码在 Windows、macOS、Linux 上就要分别编译三次。Java 选择了中间路线:

javac 把源码编译成统一的“中间语言”——字节码,它不针对任何特定系统;JVM 在运行时把字节码解释或编译成当前系统的机器码。代码只需编译一次,就可以在任何安装了 JVM 的平台上运行。

编译器 javac虚拟机 JVM
阶段编译期(编写代码后)运行期(执行程序时)
输入Java 源代码 .java字节码文件 .class
输出字节码 .class平台相关的机器指令
职责语法检查、类型检查、代码优化加载类、管理内存、执行字节码
跨平台只生成一次字节码,与操作系统无关每个平台装不同的 JVM,运行同一份字节码
💡 简单记忆:javac 编译的是“人写的代码”,JVM 执行的是“机器能跑的代码”,字节码就是它们之间的桥梁。
什么?你电脑还没装Java环境?快戳我!→

将跳转到菜鸟教程