JVM核心面试题
JVM 面试题很多,但核心都围绕类加载、内存结构、GC、执行优化和排障工具。回答时要尽量从原理讲到实践。
# 1. JVM 运行时数据区有哪些
主要包括:
- 程序计数器。
- Java 虚拟机栈。
- 本地方法栈。
- Java 堆。
- 方法区。
其中程序计数器、虚拟机栈、本地方法栈是线程私有;堆和方法区是线程共享。
# 2. 堆和栈有什么区别
堆主要存放对象实例和数组,是线程共享区域,也是 GC 重点管理区域。
栈主要存放方法调用栈帧,包括局部变量表、操作数栈、动态链接和返回地址,是线程私有区域。
堆容易出现 Java heap space,栈容易出现 StackOverflowError。
# 3. 类加载过程是什么
类加载过程包括:
加载 -> 验证 -> 准备 -> 解析 -> 初始化
验证、准备、解析统称连接。
准备阶段给静态变量分配内存并设置默认值,初始化阶段执行静态变量赋值和静态代码块。
# 4. 什么是双亲委派模型
类加载器收到类加载请求后,先委派给父加载器,父加载器无法加载时,当前加载器才尝试加载。
作用:
- 保证核心类库安全。
- 避免重复加载。
- 维护类加载层次。
SPI、Tomcat、插件系统等场景可能调整或打破双亲委派。
# 5. 如何判断对象可以被回收
JVM 主要使用可达性分析。从 GC Roots 出发,如果对象不可达,就可以被回收。
常见 GC Roots:
- 栈帧中的局部变量引用。
- 静态变量引用。
- 常量引用。
- JNI 引用。
- 活跃线程相关对象。
# 6. Minor GC、Major GC、Full GC 区别
Minor GC 通常指新生代回收。
Major GC 通常指老年代回收,但不同语境含义不完全一致。
Full GC 通常指整个堆甚至元空间相关回收,停顿影响较大。
分析时以具体 GC 日志为准。
# 7. G1 的特点是什么
G1 把堆划分为多个 Region,优先回收垃圾最多、收益最高的区域。
特点:
- Region 化管理。
- 可设置停顿目标。
- 并发标记。
- Mixed GC。
- 适合服务端应用。
JDK 9 起 G1 成为服务端默认 GC。
# 8. 什么是逃逸分析
逃逸分析判断对象是否逃出当前方法或线程。
如果对象不逃逸,JIT 可能进行:
- 标量替换。
- 同步消除。
- 减少堆分配。
它是 JVM 运行时优化的重要基础。
# 9. 如何排查 OOM
先看 OOM 类型:
Java heap space:分析堆 dump。Metaspace:分析类加载和类加载器。Direct buffer memory:分析堆外内存。unable to create native thread:分析线程数和系统限制。
不要一看到 OOM 就只调大 -Xmx。
# 10. 如何排查 CPU 飙高
步骤:
top -Hp <pid>找高 CPU 线程。- 线程 ID 转十六进制。
jstack抓线程栈。- 搜索
nid=0x...。 - 分析栈顶业务代码。
- 多次采样确认。
# 11. 阶段小结
JVM 面试题最重要的是能把概念和生产问题连起来。只会背“堆栈方法区”不够,最好能讲出这些区域出了问题如何定位、如何修复、如何验证。
# 12. 面试回答结构
回答 JVM 问题可以使用四段式:
1. 先给定义
2. 再讲机制
3. 补充常见问题
4. 最后结合生产排障
例如回答“什么是 Full GC”:
定义:Full GC 通常指覆盖整个堆甚至元空间相关区域的回收。
机制:会带来较长 STW,具体行为取决于收集器。
问题:频繁 Full GC 会导致延迟抖动。
排障:看 GC 日志触发原因、回收前后老年代变化,再决定是否 dump。
# 13. 高频追问清单
| 问题 | 面试官可能想听什么 |
|---|---|
| 堆和栈区别 | 不只是存什么,还要说线程共享/私有和异常 |
| 双亲委派 | 安全、唯一性、破坏场景 |
| G1 | Region、停顿目标、Mixed GC、Humongous |
| OOM | 分类定位,不要只说加内存 |
| CPU 高 | top -Hp + nid + jstack |
| 内存泄漏 | GC Roots 引用链 |
| JIT | 热点、内联、逃逸分析 |
# 14. Tips 快问快答
Q:面试回答要不要背参数?
A:参数可以点到,但更重要是说清楚机制和排障思路。
Q:回答 GC 要不要细到源码?
A:除非岗位要求 JVM 深度开发,一般能讲清算法、收集器取舍和日志分析就很有竞争力。
Q:不会的问题怎么答?
A:先说明已知边界,再给排查路径,比硬编一个结论更好。
Q:怎样体现生产经验?
A:把工具、日志、指标、风险和验证讲出来,而不是只背概念。