乔的Blog 返回首页

JVM垃圾回收八股

可以,我帮你把这套 JVM 垃圾回收知识串成一条完整的线,尽量按“先理解大图,再看 CMS 和 G1”的方式来讲。1. JVM 垃圾回收到底在管什么JVM 的堆主要用来放对象。因为对象会不断创建和销毁,JVM 需要自动找出“没用了的对象”并回收内存。核心目标就两个:尽快回收垃圾尽量少影响业务线程所以 GC 的设计,本质上是在 吞吐量、停顿时间、内存利用率 之间做平衡。2. 为什么会有新生代和老年代

可以,我帮你把这套 JVM 垃圾回收知识串成一条完整的线,尽量按“先理解大图,再看 CMS 和 G1”的方式来讲。

1. JVM 垃圾回收到底在管什么

JVM 的堆主要用来放对象。因为对象会不断创建和销毁,JVM 需要自动找出“没用了的对象”并回收内存。

核心目标就两个:

所以 GC 的设计,本质上是在 吞吐量、停顿时间、内存利用率 之间做平衡。


2. 为什么会有新生代和老年代

JVM 里的对象大多是“朝生夕死”的,也就是很快就没用了。

所以通常会做分代管理:

这样可以针对不同对象特征,使用不同回收策略。

常见流程是:

晋升的本质不是“按时间老了”,而是“经历了多轮 GC 还活着”。


3. 三种基础回收算法

标记-清除

先标记存活对象,再直接清掉垃圾对象。

特点:

适合:

标记-整理

先标记存活对象,再把存活对象往一边挪,整理成连续空间。

特点:

适合:

复制算法

把内存分成两块,只用一块分配对象。回收时把存活对象复制到另一块,然后整块清空原区域。

特点:

适合:


4. 为什么新生代常用复制,老年代常用标记类算法

因为对象分布不一样:

所以一般是:


5. CMS 的工作机制

CMS 全称是 Concurrent Mark Sweep,核心目标是:
尽量缩短老年代回收时的停顿时间

它主要针对老年代,特点是“并发回收”,也就是尽量让 GC 线程和用户线程同时工作。

CMS 大致分几个阶段:

  1. 初始标记

    • 很短

    • 只标记 GC Roots 直接关联的对象

    • 这个阶段会 STW

  2. 并发标记

    • 从初始标记结果出发,继续追踪整个对象图

    • 这个阶段和用户线程并发执行

  3. 重新标记

    • 修正并发标记期间用户线程造成的变化

    • 会 STW,但通常比全量回收短

  4. 并发清除

    • 把标记出的垃圾直接清掉

    • 和用户线程并发执行

CMS 的优点:

CMS 的问题:

你可以把 CMS 理解成:
用更多后台并发工作,换取更短的停顿。


6. G1 的工作机制

G1 全称 Garbage First,它的目标是:
在可控停顿时间下,尽量高效地回收整堆

G1 和传统分代收集器最大的区别是:
它把堆切成很多个 Region,不再是“新生代一整块、老年代一整块”的老式大区块思路。

这些 Region 逻辑上可以扮演:

G1 的核心思想:

G1 的典型流程

  1. 初始标记

    • 标记 GC Roots 直接引用对象

    • STW

  2. 并发标记

    • 追踪整个堆中对象的存活情况

    • 和用户线程并发

  3. 最终标记

    • 修正并发期间变动

    • STW

  4. 筛选回收 / 混合回收

    • G1 不是一次只收某一代

    • 它会把新生代和一部分老年代 Region 混着回收

    • 优先回收“垃圾最多、收益最高”的 Region

G1 的特点:

你可以把 G1 理解成:
不是整块整块地收,而是把堆切成很多小块,挑最划算的块先收。


7. CMS 和 G1 的区别

CMS

G1

简单对比一句话:


8. 你可以这样串起来记

一条完整逻辑链是:


9. 面试时可以直接这么说

JVM 垃圾回收的核心,是在对象生命周期差异的基础上做分代管理。新生代对象存活率低,常用复制算法,回收快且无碎片;老年代对象存活率高,常用标记-清除或标记-整理,以平衡空间利用率和回收成本。CMS 主要通过并发标记和并发清除来降低停顿,但容易产生碎片;G1 则把堆切成多个 Region,按收益优先做混合回收,目标是在大堆场景下实现更可预测的停顿时间。

如果你愿意,我下一条可以把这部分再整理成一份更适合背诵的“面试速记版”,或者给你画一版“新生代 / 老年代 / CMS / G1”的对比表。