JVM垃圾回收八股
可以,我帮你把这套 JVM 垃圾回收知识串成一条完整的线,尽量按“先理解大图,再看 CMS 和 G1”的方式来讲。1. JVM 垃圾回收到底在管什么JVM 的堆主要用来放对象。因为对象会不断创建和销毁,JVM 需要自动找出“没用了的对象”并回收内存。核心目标就两个:尽快回收垃圾尽量少影响业务线程所以 GC 的设计,本质上是在 吞吐量、停顿时间、内存利用率 之间做平衡。2. 为什么会有新生代和老年代
可以,我帮你把这套 JVM 垃圾回收知识串成一条完整的线,尽量按“先理解大图,再看 CMS 和 G1”的方式来讲。
1. JVM 垃圾回收到底在管什么
JVM 的堆主要用来放对象。因为对象会不断创建和销毁,JVM 需要自动找出“没用了的对象”并回收内存。
核心目标就两个:
尽快回收垃圾
尽量少影响业务线程
所以 GC 的设计,本质上是在 吞吐量、停顿时间、内存利用率 之间做平衡。
2. 为什么会有新生代和老年代
JVM 里的对象大多是“朝生夕死”的,也就是很快就没用了。
所以通常会做分代管理:
新生代:放新对象,存活率低
老年代:放活得久的对象,存活率高
这样可以针对不同对象特征,使用不同回收策略。
常见流程是:
对象先分配到 Eden
Minor GC 时,存活对象被复制到 Survivor
多次 GC 后还活着的对象,晋升到老年代
晋升的本质不是“按时间老了”,而是“经历了多轮 GC 还活着”。
3. 三种基础回收算法
标记-清除
先标记存活对象,再直接清掉垃圾对象。
特点:
优点:实现简单,不搬对象
缺点:容易产生内存碎片
适合:
对碎片不那么敏感的场景
标记-整理
先标记存活对象,再把存活对象往一边挪,整理成连续空间。
特点:
优点:减少碎片,后续分配更方便
缺点:对象要移动,成本更高
适合:
老年代这种对象存活率高的区域
复制算法
把内存分成两块,只用一块分配对象。回收时把存活对象复制到另一块,然后整块清空原区域。
特点:
优点:速度快,没有碎片
缺点:浪费一部分空间
适合:
新生代这种大部分对象很快就死的场景
4. 为什么新生代常用复制,老年代常用标记类算法
因为对象分布不一样:
新生代:死得多,活得少
复制算法只需要搬少量存活对象,成本低,而且很干净。老年代:活得多,死得少
如果也用复制算法,要搬的对象太多,空间开销也大,不划算。
所以一般是:
新生代偏向复制
老年代偏向标记-清除或标记-整理
5. CMS 的工作机制
CMS 全称是 Concurrent Mark Sweep,核心目标是:
尽量缩短老年代回收时的停顿时间
它主要针对老年代,特点是“并发回收”,也就是尽量让 GC 线程和用户线程同时工作。
CMS 大致分几个阶段:
初始标记
很短
只标记 GC Roots 直接关联的对象
这个阶段会 STW
并发标记
从初始标记结果出发,继续追踪整个对象图
这个阶段和用户线程并发执行
重新标记
修正并发标记期间用户线程造成的变化
会 STW,但通常比全量回收短
并发清除
把标记出的垃圾直接清掉
和用户线程并发执行
CMS 的优点:
停顿时间短
适合对响应时间敏感的应用
CMS 的问题:
会产生碎片
对 CPU 比较敏感
需要更复杂的并发控制
如果碎片太多,可能触发更重的整理类回收
你可以把 CMS 理解成:
用更多后台并发工作,换取更短的停顿。
6. G1 的工作机制
G1 全称 Garbage First,它的目标是:
在可控停顿时间下,尽量高效地回收整堆
G1 和传统分代收集器最大的区别是:
它把堆切成很多个 Region,不再是“新生代一整块、老年代一整块”的老式大区块思路。
这些 Region 逻辑上可以扮演:
新生代区域
老年代区域
巨型对象区域
G1 的核心思想:
优先回收收益最大的 Region
尽量把停顿控制在目标时间内
G1 的典型流程
初始标记
标记 GC Roots 直接引用对象
STW
并发标记
追踪整个堆中对象的存活情况
和用户线程并发
最终标记
修正并发期间变动
STW
筛选回收 / 混合回收
G1 不是一次只收某一代
它会把新生代和一部分老年代 Region 混着回收
优先回收“垃圾最多、收益最高”的 Region
G1 的特点:
停顿可预测
适合大堆内存
比传统分代更灵活
通过 Region 化减少大范围一次性回收的压力
你可以把 G1 理解成:
不是整块整块地收,而是把堆切成很多小块,挑最划算的块先收。
7. CMS 和 G1 的区别
CMS
主要关注:缩短停顿
主要针对:老年代
回收方式:并发标记、并发清除
问题:容易产生碎片
G1
主要关注:可预测停顿 + 大堆效率
管理方式:Region 化
回收方式:并发标记 + 混合回收
优点:更灵活,碎片问题更容易控制
简单对比一句话:
CMS:尽量少停顿,但老年代容易碎片化
G1:按 Region 管理,既想少停顿,也想更均衡地回收整个堆
8. 你可以这样串起来记
一条完整逻辑链是:
JVM 管理堆内存
因为对象有“朝生夕死”特性,所以引入分代思想
新生代适合复制算法,老年代适合标记-清除或标记-整理
CMS 是面向老年代、追求低停顿的并发收集器
G1 是基于 Region 的分代型收集器,目标是更可控的停顿和更均衡的回收
9. 面试时可以直接这么说
JVM 垃圾回收的核心,是在对象生命周期差异的基础上做分代管理。新生代对象存活率低,常用复制算法,回收快且无碎片;老年代对象存活率高,常用标记-清除或标记-整理,以平衡空间利用率和回收成本。CMS 主要通过并发标记和并发清除来降低停顿,但容易产生碎片;G1 则把堆切成多个 Region,按收益优先做混合回收,目标是在大堆场景下实现更可预测的停顿时间。
如果你愿意,我下一条可以把这部分再整理成一份更适合背诵的“面试速记版”,或者给你画一版“新生代 / 老年代 / CMS / G1”的对比表。