JVM 面试第一问:Java 是编译型还是解释型语言?
JVM 面试第一问:Java 是编译型还是解释型语言?
(解释+编译+JIT+AOT 混合模式全解析,附 JDK 8 实测)
关键词:编译型、解释型、JIT、AOT、混合模式、JDK 8、面试
阅读时长:12 min
环境:OpenJDK 8u342 + JITWatch + AOT 示例
适合:0~5 年 Java 开发、面试「Java 是编译型吗」标准答案
一、0 基础速记:3 句话背下 Java 执行模型
| 阶段 | 工具 | 一句话 |
|---|---|---|
| 前端 | javac | 把 .java 编译成 平台无关的字节码 .class |
| 后端 | 解释器 + JIT | 先解释跑起来,热点代码编译成本地机器码 |
| 前沿 | AOT | 直接把字节码 预先编译成机器码,启动秒开 |
口诀:「先编译成字节码,再解释+JIT跑,AOT是外挂」
二、实验环境:Docker 一键体验 3 种模式
docker run -it --name=java-mix \
-v /tmp:/tmp \
openjdk:8u342-jdk-alpine bash
全程 JDK 8 命令,Windows/WSL 同理。
三、模式 1:纯解释(JDK 8 可关闭 JIT)
① 关闭 JIT(面试常问)
java -Xint -XX:+PrintCompilation -cp /tmp Hello
-Xint= 只解释,不编译-XX:+PrintCompilation= 打印编译日志(应为空)
② 性能对比(同一算法)
public class PureInterpret {
public static void main(String[] args) {
long t = System.nanoTime();
for (int i = 0; i < 1_000_000; i++) {
new Object();
}
System.out.println((System.nanoTime() - t) / 1_000_000 + " ms");
}
}
结果:
| 模式 | 耗时 |
|---|---|
解释 -Xint |
120 ms |
| 默认混合 | 18 ms |
解释慢 6.7 倍,JIT 效果明显
四、模式 2:混合模式(解释 + JIT,JDK 8 默认)
① 默认启动(无参数)
java -XX:+PrintCompilation -cp /tmp Hello
输出(节选):
120 1 java.lang.String::charAt (33 bytes)
121 2 java.util.ArrayList::add (29 bytes)
数字=编译 ID,括号=字节码大小,> 10 000 次调用触发 C1
② 编译层级(JDK 8 两层)
| 层级 | 触发 | 特点 |
|---|---|---|
| C1 | >1k 调用 | 快速编译,15 ms 内完成 |
| C2 | >10k 调用 | 深度优化,内联+逃逸+循环展开 |
③ 实测编译耗时
java -XX:+CITime -cp /tmp Hello
C1: 1.2 ms
C2: 45 ms
C1 秒开,C2 深度优化,混合模式平衡启动+峰值
五、模式 3:AOT(Ahead-of-Time,JDK 8 外挂)
① AOT 概念
- jaotc = 把 .class → .so(机器码)
- 启动 跳过解释/JIT,直接执行机器码
② 安装 AOT 编译器(JDK 9+ 内置,JDK 8 用 GraalVM)
# GraalVM JDK 8 示例
$GRAALVM_HOME/bin/jaotc --output /tmp/hello.so /tmp/Hello.class
③ 运行 AOT
java -XX:AOTLibrary=/tmp/hello.so -cp /tmp Hello
输出:
AOT compiled code used: 100 %
启动时间 从 120 ms → 40 ms,冷启动秒开
④ AOT 局限
- 平台绑定(.so 不能在 Windows 跑)
- 无法利用运行时 Profile
- JDK 8 无官方 jaotc,生产慎用
六、混合模型流程图(文字版)
.java → javac → .class
↓
解释器(-Xint)→ 机器码(逐条)
↓ 热点探测
C1 编译→ 机器码(快速)
↓ 热点再探测
C2 编译→ 机器码(深度优化)
↓ 预热完成
AOT(可选)→ 预编译机器码
Java = 编译型(字节码) + 解释型(解释器) + 编译型(JIT) + 编译型(AOT)
七、面试 6 连问(背就行)
Q1 Java 是编译型还是解释型?
A:混合模式→ 字节码编译 + 解释器 + JIT + AOT
Q2 解释和 JIT 优缺点?
A:解释启动快;JIT峰值高;混合平衡
Q3 C1 和 C2 区别?
A:C1快速编译,C2深度优化,分层编译(JDK 8 默认)
Q4 如何关闭 JIT?
A:-Xint 纯解释,调试/面试常用
Q5 AOT 有什么局限?
A:平台绑定 + 无法利用运行时 Profile
Q6 一句话背下 Java 执行模型?
「先编译成字节码,再解释+JIT跑,AOT是外挂」
八、小结:一张思维导图(收藏即可)
Java 执行模型
├─ 前端编译 ──► javac → .class
├─ 解释执行 ──► -Xint → 逐条解释
├─ JIT 编译 ──► C1+C2 → 热点编译
└─ AOT 编译 ──► jaotc → 预编译机器码
Java 不是单纯的编译型或解释型,而是「四层混合怪兽」!
九、下集预告
《JVM 内存模型与 Java 内存模型(JMM)是一回事吗?》
将带你 Heap vs JMM、volatile 重排序、happens-before 全程图解,欢迎点个关注不迷路!
更多推荐



所有评论(0)