JVM

Java Fundamentals

编译器 × 虚拟机

编译器负责“翻译”,虚拟机负责“执行”。从 javacJVM,看一段 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环境?快戳我!

将跳转到菜鸟教程