Files

139 lines
6.9 KiB
Markdown
Raw Permalink Normal View History

2026-08-09 19:06:40 +08:00
---
tags: [test/review, java, gc-algorithm, cms, g1, zgc, young-gen]
create time: 2026-08-09 12:00
---
# 垃圾回收算法与收集器_测试题
## 概述
本测试覆盖标记-清除/复制/整理三种经典 GC 算法、分代理论依据,以及 CMS、G1、ZGC 三大收集器的设计原理和选型策略,共 10 道题目(6 道选择题 + 3 道填空题 + 1 道简答题)。
---
## 一、选择题(6道,由浅入深)
> **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景
### Q1(基础)— 考察定义层面
新生代 Eden:S0:S1 的经典比例设计中,Eden 区占新生代的份额大约是:
A. 1/2(50%)
B. 1/3(约 33%)
C. 4/5(80%)
D. 9/10(90%)
### Q2(基础)— 考察概念记忆
以下哪种 GC 算法的主要缺点是**会产生大量内存碎片**?
A. 标记-复制(Mark-Copy)
B. 标记-整理(Mark-Compact)
C. 标记-清除(Mark-Sweep)
D. G1 的 Mixed GC
### Q3(进阶)— 考察核心原理
CMS 收集器有四个阶段,其中**不会暂停用户线程**的阶段是:
A. 初始标记(Initial Mark)
B. 并发标记(Concurrent Mark)
C. 预标记(Re-Mark)
D. 以上三个阶段都会 STW
### Q4(进阶)— 考察比较与辨析
G1 收集器与传统的 CMS 收集器相比,最核心的架构区别在于:
A. G1 不再物理分隔新生代和老年代,而是将堆划分为多个大小相等的 Region
B. G1 只使用标记-清除算法,而 CMS 使用标记-复制算法
C. G1 的所有 GC 动作都在单线程内串行完成
D. G1 不支持并发回收,必须依赖 Full GC
### Q5(深入)— 考察场景推理
某服务堆大小约为 16GB,要求 GC 暂停时间控制在 200ms 以内,对吞吐量有一定要求但不追求极致低延迟。根据收集器选型决策树,最合适的选择是:
A. CMS
B. G1
C. ZGC
D. Parallel Old
### Q6(深入)— 考察边界场景
ZGC 能够实现暂停时间不超过 10ms(无论堆大小)的核心技术是:
A. 在写屏障中记录所有引用修改,然后批量重定位
B. 染色指针 + 加载屏障,将原本沉重的写屏障移到加载时机
C. 利用多核并行地在一个 STW 窗口内完成全量回收
D. 将所有对象分配到连续内存区域,避免引用失效
---
## 二、填空题(3道)
### F1 — 填空1
CMS 收集器有三个显著缺陷:**浮动垃圾**(并发清扫阶段产生的新对象只能等下一次 GC 处理)、__(1)__(基于标记-清除算法容易产生碎片)、以及 CPU 资源敏感(并发阶段和用户代码共享 CPU)。CMS 在 JDK __(2)__ 中被彻底移除。
> **提示**: 回顾 CMS 缺陷部分的具体描述和生命周期。
### F2 — 填空2
G1 收集器中有一个特殊的概念叫 ROI(Return of Investment),用于排序 Region 的回收优先级——优先回收__(1)__最大的 Region。此外,超过半个 Region 大小的超大对象会直接分配到__(2)__ Region,以避免碎片问题。
> **提示**: ROI = 回收得到的空间 / 花费的时间,超大对象的特殊命名与其用途相关。
### F3 — 填空3
根据选型决策树:堆 < 4GB 推荐 Parallel GC(吞吐优先)或 CMS(JDK 8 低延迟需求);4GB ≤ 堆 ≤ 32GB 推荐 __(1)__;堆 > 32GB 且要求暂停 < 10ms 推荐 __(2)__。
> **提示**: 这是生产环境中最常用的两个收集器选择分界线。
---
## 三、简答题(1道)
### S1
某电商大促活动即将开始,负责团队正在做线上 GC 压测。现有三个待选收集器:CMS、G1、ZGC。已知以下条件:
- 堆大小约 24GB
- 要求 GC 暂停时间尽量短(P99 < 300ms)
- 业务允许一定的吞吐量损失
- 当前运行在 JDK 11 之上
请回答:
1. 你会推荐哪个(些)收集器?给出决策理由。
2. ZGC 相比 G1 的核心优势是什么?它的两项关键技术名词是什么?
3. 如果在压测中发现使用 CMS 时频繁出现 Full GC,可能的原因是什么?(至少给出两条)
> **答题框架提示**:
> - 第 1 问先看堆大小落在选型树的哪个区间
> - 第 2 问直接提取 ZGC 的技术细节
> - 第 3 问从 CMS 的三个缺陷出发推导
---
## 参考答案与解析
### 选择题答案
| 题号 | 正确答案 | 解析 |
|------|---------|------|
| Q1 | C | HotSpot 通过 Eden:S0:S1 = 8:1:1 的比例设计,Eden 占 8/10 = 80%,让绝大多数新对象直接分配到 Eden。只有少量长寿对象才进入 Survivor。 |
| Q2 | C | 标记-清除算法不移动对象、不复制,只是在清除未标记区域时留下空洞,产生碎片。标记-复制和标记-整理都能避免碎片。 |
| Q3 | B | CMS 的初始标记和预标记都需要短暂 STW,并发标记和并发清扫是完全与用户线程并行的。所以选 B。 |
| Q4 | A | G1 的最大创新是将堆划分为最多 2048 个 Region(每个 1~32MB),不再物理分隔新生代和老年代。B 错误(G1 不使用纯标记-清除),C 错误(G1 并行并发),D 错误(G1 支持并发)。 |
| Q5 | B | 堆大小 24GB 落在 4GB~32GB 区间,选型决策树明确指出这个范围推荐 G1。ZGC 虽然也适用但成本更高(吞吐量略低),Parallel Old 吞吐优先不适合低延迟场景。 |
| Q6 | B | ZGC 的核心创新是染色指针(在指针高位 bit 编码颜色信息)和加载屏障(读引用时才执行重定位),将写屏障移到加载时机。A 描述的是传统写屏障方式。 |
### 填空题答案
| 题号 | 答案 | 解析 |
|------|------|------|
| F1 | (1)内存碎片 (2)JDK 14 | CMS 基于标记-清除算法,必然产生碎片,可能导致大对象无法分配而提前触发 Full GC。CMS 在 JDK 9 标记废弃,JDK 14 彻底移除。 |
| F2 | (1)ROI(回收价值) (2)Humongous | G1 按 ROI 排序优先回收性价比最高的 Region。超大对象(超过半 Region)直接放入 Humongous Region 避免跨区碎片。 |
| F3 | (1)G1 (2)ZGC | 4GB~32GB 是 G1 的主战场(大多数生产环境的默认选择),>32GB 且要求低延迟时切换 ZGC。 |
### 简答题参考答案
S1:**参考答案要点**:
1. 堆大小 24GB 落在 4GB~32GB 区间,推荐 G1 作为首选。如果预算允许且对延迟要求更严苛,也可以评估 ZGC。JDK 11 以上已支持 ZGC 生产使用。
2. ZGC 的核心优势是暂停时间绝对不超过 10ms,与堆大小无关。两项关键技术:染色指针(Colored Pointers)和加载屏障(Load Barrier)。
3. CMS 频繁 Full GC 的可能原因:① 内存碎片过多导致大对象无法在 Eden 分配直接进入老年代,老年代很快满;② CMS 并发清扫阶段产生的"浮动垃圾"积累到下一次的 Full GC;③ 老年代阈值配置不合理,GC 未能及时触发。
**评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点。
## 关联笔记
- [[01.Java/jvm/JVM 内存模型]]