JVM 内存结构与垃圾回收

返回 面试 · 速查全集 Java常见面试题

详解 JVM垃圾回收


运行时数据区

区域线程共享存什么OOM
对象实例、数组Java heap space
方法区 / 元空间类元数据、常量、静态变量Metaspace OOM
虚拟机栈栈帧、局部变量、引用StackOverflow / 无法新建线程
本地方法栈Native 方法同上
程序计数器当前字节码行号不会 OOM
┌─────────────────────────────────────┐
│  堆 Heap(Young + Old)              │  ← 对象
├─────────────────────────────────────┤
│  元空间 Metaspace(JDK8+,本地内存)   │  ← 类信息
└─────────────────────────────────────┘
     每线程:虚拟机栈 + 程序计数器

堆 vs 栈:堆存对象;栈存局部变量表、操作数栈、方法出口(引用指向堆中对象)。


分代模型

区域说明
Eden新对象优先分配
Survivor S0/S1Minor GC 存活对象复制,年龄 +1
Old长期存活、大对象(直接进老年代可配置)

Minor GC:新生代;频繁、较快。
Full GC / Major GC:常含老年代;停顿长,应尽量减少。


如何判断可回收

可达性分析:从 GC Roots(栈中引用、静态字段、常量、JNI 等)出发,不可达对象可回收。


常见 GC 算法

算法思路缺点
标记-清除标记存活,清除其余碎片
标记-复制存活复制到另一块空间浪费(新生代常用)
标记-整理存活移到一端移动成本

收集器(常问)

收集器特点
Serial / Parallel新生代单线程 / 多线程
CMS老年代并发标记清除,低停顿,已逐步被 G1 替代
G1分区 Region,可设 -XX:MaxGCPauseMillis 目标停顿
ZGC / Shenandoah超低延迟,染色指针 / 并发整理

类加载(简)

加载 → 验证 → 准备 → 解析 → 初始化。详见 类加载与双亲委派


OOM 排查

  1. 看日志:Java heap space / Metaspace / GC overhead limit
  2. -XX:+HeapDumpOnOutOfMemoryError
  3. jmap -dump + MAT 看 dominator tree、泄漏引用链
  4. 常见原因:缓存无上限、ThreadLocal 未 remove、大集合、元空间类加载过多

工具见 jmapjstack


常见面试题

Q:对象一定在堆上吗?
A:多数在堆;逃逸分析后可能栈上分配或标量替换(JIT)。

Q:强软弱虚引用?
A:强默认;软内存不足回收;弱 GC 即回收(ThreadLocalMap key);虚用于跟踪回收时机(PhantomReference)。

Q:Minor GC 会触发 Full GC 吗?
A:可能——老年代空间不足、担保失败、System.gc() 建议等。

Q:如何调优 GC?
A:先 metrics(停顿、吞吐);设堆大小;选 G1/ZGC;查泄漏而非盲目调参。


相关笔记