JVM 是 Java 后端绕不开的核心基础。学习 JVM 的目标不是背概念,而是能解释对象如何创建和回收、类如何加载、GC 如何影响应用、参数如何配置,以及线上 OOM、频繁 GC、CPU 飙高等问题应该如何排查。
适合谁看
- 想系统学习 JVM 的 Java 后端开发者。
- 准备 JVM 内存、类加载、GC、参数调优和线上排查相关面试题的同学。
- 已经参与过线上服务维护,但对 GC 日志、堆转储、线程栈和 JDK 工具不熟的读者。
- 想继续深入 Spring、Netty、中间件或性能优化的工程师。
JVM 是 Java 后端绕不开的核心基础。学习 JVM 的目标不是背概念,而是能解释对象如何创建和回收、类如何加载、GC 如何影响应用、参数如何配置,以及线上 OOM、频繁 GC、CPU 飙高等问题应该如何排查。
JVM 面试很少停在“堆和栈有什么区别”。回答完内存区域,面试官通常会继续问对象怎样分配、哪些对象可以回收、一次 GC 为什么会停顿,以及线上出现 OOM、频繁 Full GC 或 CPU 飙高时怎样排查。
这篇文章是 JavaGuide JVM 专题的面试复习入口,问题按内存与对象、类文件与类加载、垃圾回收、参数与诊断工具、线上问题排查五部分整理。每个问题的完整答案放在对应专题文章中。
时间比较紧的话,可以先看 JVM 常见面试题总结,把答不完整的问题标出来,再回到本文和专题文章补细节。
告警刚响,排查很容易被监控页面上最显眼的那条曲线带着走。看到 CPU 高就抓线程栈,看到 Full GC 就查堆,发布刚结束就准备回滚。可这些现象经常互相传导:慢 SQL 会占住数据库连接,连接池等待又会拖住业务线程,最后可能同时看到延迟、错误率和 CPU 上升。单看其中一项,很难定根因。
故障还在扩大时,先按预案控制影响。实例还有余量,确认取证不会继续压垮服务后,再保存日志、Trace、线程栈和内存信息。重启往往能暂时恢复,但也会清掉现场;为了抓取 Heap Dump 一直让异常实例承载流量,同样可能把问题拖大。现场情况决定先摘流量、回滚,还是先取证。
下面只讨论 Java 应用侧的常见问题。如果证据已经指向容器调度、内核、网络设备或云平台,需要转到相应平台的监控和操作手册继续排查,这里不展开。
本文由 JavaGuide 翻译自 https://www.baeldung.com/jvm-parameters,并对文章进行了大量的完善补充。
文档参数 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.htmlJDK 版本:1.8 为主,也会补充新版本常用参数
开始介绍类加载器和双亲委派模型之前,简单回顾一下类加载过程。

加载是类加载过程的第一步,主要完成下面 3 件事情:
在 Java 中,JVM 可以理解的代码就叫做 字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效,而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。
Clojure(Lisp 语言的一种方言)、Groovy、Scala、JRuby、Kotlin 等语言都是运行在 Java 虚拟机之上。下图展示了不同的语言被不同的编译器编译成 .class 文件最终运行在 Java 虚拟机之上。.class 文件的二进制格式可以使用 WinHex 查看。
类从被加载到虚拟机内存中开始到卸载出内存为止,它的整个生命周期可以简单概括为 7 个阶段:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。其中,验证、准备和解析这三个阶段可以统称为连接(Linking)。
这 7 个阶段的顺序如下图所示:

这些命令在 JDK 安装目录下的 bin 目录下:
jps (JVM Process Status): 类似 UNIX 的 ps 命令。用于查看所有 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息;jstat(JVM Statistics Monitoring Tool): 用于收集 HotSpot 虚拟机各方面的运行数据;jinfo (Configuration Info for Java) : Configuration Info for Java,显示虚拟机配置信息;jmap (Memory Map for Java) : 生成堆转储快照;jhat (JVM Heap Dump Browser) : 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果。JDK9 移除了 jhat;jstack (Stack Trace for Java) : 生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。如果没有特殊说明,都是针对的是 HotSpot 虚拟机。
本文基于《深入理解 Java 虚拟机:JVM 高级特性与最佳实践》进行总结补充。
常见面试题:
- 如何判断对象是否死亡(两种方法)。
- 简单的介绍一下强引用、软引用、弱引用、虚引用(虚引用与软引用和弱引用的区别、使用软引用能带来的好处)。
- 如何判断一个常量是废弃常量
- 如何判断一个类是无用的类
- 垃圾收集有哪些算法,各自的特点?
- HotSpot 为什么要分为新生代和老年代?
- 常见的垃圾回收器有哪些?
- 介绍一下 CMS,G1 收集器。
- Minor Gc 和 Full GC 有什么不同呢?