航海王启航和之国篇
1.39 GB · 2025-10-03
一句话结论:
Java 的“计算”是在一台称为 JVM(Java 虚拟机) 的栈式抽象机上执行字节码完成的。源代码被编译为平台无关的 .class
文件,由类加载器加载,经过验证与链接,在执行引擎(解释器 + JIT)上运行;对象在堆上分配,由垃圾回收器回收;线程协作遵循**JMM(Java 内存模型)**的可见性与有序性约束。
牢记三大核心抽象:
面试一句话话术:
“Java 通过字节码 + 栈式虚拟机 + JMM + GC四件套,统一了语言与运行时的抽象,这就是它从编译到运行的计算模型核心。”
编译器(javac)在做什么?
for-each
、自动装箱、lambda(通过 invokedynamic
等)转为更基础形态。final
常量内联等。记忆法:源代码是“人类友好”,字节码是“机器友好”。编译阶段确定“能不能做”,运行阶段关注“做得快不快”。
源码:
public class Demo {
public static int add(int a, int b) {
return a + b;
}
概念化的字节码片段(示意):
0: iload_0 // 把局部变量表的 a 入操作数栈
1: iload_1 // 把 b 入栈
2: iadd // 栈顶两个 int 相加,结果压回栈
3: ireturn // 返回栈顶 int
要点:
i
, l
, f
, d
, a
),如 iadd
、fadd
。invokestatic
、invokevirtual
、invokespecial
、invokeinterface
、invokedynamic
。类加载器(ClassLoader) 与双亲委派:
链接(Linking)与初始化:
static
字段分配空间并赋默认值。<clinit>
(静态初始化块/静态变量初始化)。面试话术:
“类加载是找进来,链接是站稳脚,初始化是跑起来。”
按线程私有:
long/double
占两格)、操作数栈、返回地址/动态链接。按进程共享:
面试高频点:
free
?分代假设:大多数对象**“朝生暮死”**。
常见收集器(了解特性与取舍):
面试话术:
“挑 GC 看业务:吞吐 vs. 延迟的权衡;堆大小、对象存活分布决定收集器选择。”
JMM 解决三个问题:可见性、原子性、有序性。
synchronized
的解锁先行于后续加锁);volatile
写先行于后续读;start
)与终止(join
);**volatile**
:提供可见性 + 禁止重排序(不保证复合操作原子性)。**synchronized**
:基于监视器锁,原子性 + 可见性 + 有序性。AtomicStampedReference
等)。双重检查锁(DCL)示意:
class Singleton {
private static volatile Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) { // 第一次检查(无锁,快路径)
synchronized (Singleton.class) {
if (INSTANCE == null) { // 第二次检查(有锁,安全)
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
面试提醒:为何 INSTANCE
**必须 ****volatile**
?
防止指令重排导致“引用已可见但对象未初始化完成”的安全发布问题。
Code
属性中维护异常处理表;发生异常时 VM 查表跳转到对应 catch
块。invokestatic
、invokespecial
;invokevirtual
/invokeinterface
基于运行时接收者类型;**invokedynamic**
:延迟绑定,支撑 lambda、动态语言特性。main
到进程内的世界main
方法启动,第一批主动使用的类触发初始化链。**jlink**
可裁剪运行时打包,减小分发体积。**volatile**
** 与 **synchronized**
区别?**volatile
解决可见性与有序性,不保证复合操作原子性;synchronized
提供互斥,因此具备原子性+可见性+有序性。**invokedynamic**
** 有何用?**[.java 源码]
│ javac
▼
[.class 字节码] → [类加载器:Bootstrap/Platform/App/自定义]
│ │
│ 验证/准备/解析/初始化
▼ ▼
[运行时数据区] ──(PC/栈/本地栈 | 堆 | 元空间)
│
├─> [执行引擎:解释器] —— 冷代码快启动
└─> [JIT 编译:OSR/内联/逃逸分析/去优化] —— 热代码高性能
│
└─> [GC:分代/分区/低停顿收集器] —— 自动内存管理
│
└─> [JMM:happens-before/volatile/synchronized/CAS] —— 并发正确性
电梯答复模板:
“Java 程序先被 javac
编译成字节码,由类加载器加载并在验证/链接/初始化后进入运行。JVM 是栈式虚拟机,每次方法调用对应一个栈帧,指令在操作数栈上计算。对象在堆上分配,由GC自动回收。执行引擎先解释,热点方法由 JIT 编译成本地代码以提速。多线程共享内存受 JMM 约束,volatile
和 synchronized
保证可见性与有序性。这就是 Java 从编译到运行的核心计算模型。”
long/double
占两槽位。volatile
与 synchronized
。java.util.concurrent
)源代码当你把“栈式字节码 + 类加载/链接 + 执行引擎 + GC + JMM”这一条主线讲顺,Java 的“编译到运行模型”就真正入脑了。面试时,围绕这条主线展开,既体系化又能深入细节,拿分稳健。