Skip to content

01-JVM 虚拟机面试题

对应原始资料:10-面试热点课件/JVM优化及面试热点分析.md12-BAT/09-JVM虚拟机篇

一、JVM 内存结构

Q1:说一说 JVM 运行时数据区

区域线程私有存放异常
程序计数器 PC当前指令地址
虚拟机栈栈帧(局部变量、操作数栈)StackOverflowError / OOM
本地方法栈native 方法同上
堆 Heap对象、数组(GC 主战场)OutOfMemoryError
方法区(元空间 Metaspace,JDK 8+)类信息、常量池、静态变量OOM

JDK 8 把永久代(PermGen)替换为元空间(Metaspace),元空间用本地内存,不容易 OOM。 字符串常量池 JDK 7 起从永久代搬到堆。

Q2:堆的分代

  • 新生代 = Eden : S0 : S1 = 8 : 1 : 1。
  • 老年代:长期存活的对象。
  • 大对象直接进老年代。

二、对象创建与内存

Q3:new 一个对象的过程

  1. 类加载检查。
  2. 分配内存(指针碰撞 / 空闲列表)。
  3. 内存空间初始化为零值。
  4. 设置对象头(Mark Word、类型指针、数组长度)。
  5. 执行 <init> 构造方法。

Q4:对象内存布局

  • 对象头:Mark Word(hash、GC 年龄、锁状态)、类型指针。
  • 实例数据:字段。
  • 对齐填充:8 字节对齐。

三、垃圾回收(GC)

Q5:如何判断对象死亡

  • 引用计数法(不用,循环引用问题)。
  • 可达性分析:从 GC Roots 出发能否到达。GC Roots:
    • 栈中局部变量引用。
    • 方法区静态变量、常量引用。
    • 本地方法栈 JNI 引用。

Q6:四种引用

  • 强引用 Object o = new ...:永不回收(除非置 null)。
  • 软引用 SoftReference:内存不足才回收(缓存)。
  • 弱引用 WeakReference:下次 GC 必回收(ThreadLocal、WeakHashMap)。
  • 虚引用 PhantomReference:跟踪对象被回收(管理直接内存)。

Q7:GC 算法

  • 标记-清除:碎片多。
  • 标记-复制:新生代用,浪费空间。
  • 标记-整理:老年代用,慢但无碎片。
  • 分代收集:新生代复制、老年代整理。

Q8:常见的垃圾收集器

收集器特点
Serial / Serial Old新/老单线程,client 模式
ParNewSerial 多线程版
Parallel Scavenge / Parallel Old新/老吞吐量优先(JDK 8 默认)
CMS低延迟,标记清除(已废弃)
G1全堆Region 化,可预测停顿(JDK 9+ 默认)
ZGC / Shenandoah全堆染色指针,亚毫秒停顿

Q9:什么时候触发 Full GC

  • 老年代满。
  • 元空间满。
  • System.gc()(建议,非强制)。
  • 担保失败 / 并发失败。

Q10:GC 调优思路

  • 看日志/GC 日志:-Xloggc、jstat、VisualVM、arthas。
  • 关注吞吐量、停顿时间、GC 频率。
  • 合理设置 -Xms -Xmx(相等避免扩容)、新生代老年代比例。

四、类加载机制

Q11:类加载过程

加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载

  • 准备:静态变量分配内存赋默认值(0)。
  • 初始化:执行 <clinit>(静态代码块 + 静态变量赋值)。

Q12:双亲委派模型

加载时先委托父加载器加载,失败才自己加载。

启动类加载器(rt.jar)

扩展类加载器(ext/*.jar)

应用类加载器(classpath)

自定义加载器

作用:防止核心类被篡改、避免重复加载。

Q13:打破双亲委派的场景

  • SPI:JDBC 用 Thread.contextClassLoader
  • Tomcat:每个 webapp 独立 ClassLoader,隔离应用。
  • 热部署:自定义 ClassLoader 重新加载类。

五、内存溢出排查

Q14:OOM 怎么排查

  1. java.lang.OutOfMemoryError 的类型:
    • Java heap space:堆溢出,可能内存泄漏。
    • GC overhead limit exceeded:GC 花费 > 98% 时间但回收 < 2%。
    • Metaspace:类太多(动态生成、CGLIB)。
    • Direct buffer memory:NIO 直接内存。
  2. 加参数 -XX:+HeapDumpOnOutOfMemoryError,dump 堆。
  3. 用 MAT / jvisualvm 分析 hprof,找大对象和引用链。
  4. 用 arthas 在线诊断。

六、JVM 调优参数常用

-Xms2g -Xmx2g                # 初始/最大堆
-Xmn1g                       # 新生代
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/log/oom.hprof

高频考点速记

  • JVM 三大区域:堆(GC)、栈(线程私有)、方法区(元空间)。
  • 判活:可达性分析 + GC Roots。
  • 双亲委派 = 安全 + 避免重复加载。
  • G1:Region + 可预测停顿。
  • CMS 四阶段:初始标记 → 并发标记 → 重新标记 → 并发清除。