本文目录导读:

这是一个非常经典且重要的JVM面试题,CMS和G1都是低延迟垃圾回收器,但它们的核心设计思想和适用场景有很大不同。
我将从设计目标、工作步骤、核心特点、优缺点、适用场景几个维度进行对比分析。
核心区别一览
| 特性 | CMS (Concurrent Mark Sweep) | G1 (Garbage First) |
|---|---|---|
| 设计目标 | 最短停顿时间,追求低延迟 | 可预测的停顿时间,兼顾吞吐量与延迟 |
| 堆内存结构 | 分代(新生代 + 老年代),物理隔离 | 分区(Region),逻辑分代,物理不分代 |
| 算法 | 标记-清除 | 标记-整理 + 复制 |
| 主要步骤 | 初始标记 -> 并发标记 -> 重新标记 -> 并发清除 | 初始标记 -> 并发标记 -> 最终标记 -> 筛选回收 |
| GC触发方式 | 老年代占用达到阈值(-XX:CMSInitiatingOccupancyFraction) | 预估GC停顿时间,计算回收收益最高的Region |
| 碎片问题 | 有(产生内存碎片,可能导致Full GC) | 无(基于Region复制/整理,不产生碎片) |
| Full GC | 发生碎片或晋升失败时,退化为Serial Old(单线程,极慢) | 发生并发标记失败或晋升失败时,退化为Serial Old(单线程) |
| Java版本 | JDK 9开始标记为废弃,JDK 14正式移除 | JDK 7引入,JDK 9起成为默认GC |
CMS详解(已淘汰,但思想重要)
工作流程(4步)
- 初始标记(STW,很短):标记GC Roots直接关联的对象,以及年轻代指向老年代的引用。
- 并发标记(无STW):从GC Roots开始遍历整个老年代,标记所有存活对象。耗时最长,与应用线程并发执行。
- 重新标记(STW,比初始标记长):修正并发标记期间因用户线程继续运行而产生变动的对象标记记录。
- 并发清除(无STW):清除未被标记的对象,回收内存。
优点
- 并发标记 & 并发清除:真正做到了低延迟,停顿时间极短。
- 对老年代回收效率高(在碎片不严重时)。
痛点
- 内存碎片:标记-清除算法必然导致碎片,当碎片太多,无法为大对象分配连续空间时,触发Full GC(Serial Old,单线程,非常慢)。
- CPU敏感:并发阶段占用CPU资源,在CPU核心少的环境下会拖慢应用。
- 浮动垃圾:并发标记阶段产生的垃圾无法在本次回收,只能等下次,因此需要预留空间给并发标记线程执行,不能等到堆满才触发。
- 并发模式失败(Concurrent Mode Failure):如果并发标记期间,预留空间不够,触发Full GC。
G1详解(现代默认)
G1的核心思想是 “把堆分成多个独立的小块(Region),每次只回收收益最高(垃圾最多)的那一批”。
堆内存结构(Region)
- Region:堆被分成约2048个大小相等(1MB-32MB)的Region。
- Eden / Survivor / Old / Humongous(巨型对象):这些逻辑分代对应不同Region,但Region是动态分配的,某个Region之前是老年代,回收后可变为年轻代。
- Humongous Region:专门存放大小超过Region 50%的对象,防止大对象在正常Region间移动。
工作流程(5步)
- 初始标记(STW,很短):标记GC Roots直接关联的对象。同时完成了Young GC(年轻代回收)。
- 并发标记(无STW):从GC Roots开始遍历整个堆(包括老年代),标记存活对象。
- 最终标记(STW,略长):处理并发标记短暂遗漏的引用变更(SATB,Snapshot-At-The-Beginning算法)。
- 筛选回收(STW,可预测):核心步骤,G1会统计所有Region的回收收益(回收垃圾量 / 回收耗时),然后选择一批收益最高的Region进行回收,回收时使用复制算法,将存活对象压缩到另一个Region,彻底消除碎片。
- 可选:并发清除(无STW):回收完全没对象的Region。
关键特性
- 停顿时间模型:通过
-XX:MaxGCPauseMillis(默认200ms)指定目标停顿时间,G1会动态调整年轻代大小、Region回收数量等来尽量满足此目标。 - 无碎片:因为回收时用了复制/整理算法。
- 可预测停顿:通过筛选回收,每次STW时间可控。
优点
- 低延迟:停顿时间可控,且通常远低于CMS的Full GC风险。
- 高吞吐量:在停顿时间目标下,尽量多回收内存。
- 自动调优:不需要额外设置太多参数(如CMS的
-XX:CMSInitiatingOccupancyFraction)。
缺点
- 内存占用略高:需要额外的Remembered Set(记录跨Region引用)数据结构,约5%-10%的堆内存。
- 响应时间不如ZGC/Shenandoah:虽然优于CMS,但在极低延迟(<10ms)场景下不如ZGC。
总结对比:何时用哪个?
-
CMS(历史选择):
- 适合JDK 8及以前,对停顿时间敏感,且堆内存不大(<4GB~6GB) 的场景。
- 注意:如果堆很大(>6GB),CMS的碎片和Full GC风险会指数级上升。
-
G1(现代选择):
- JDK 9及以上的默认选择。
- 适合堆内存较大(>6GB),且需要可预测、较低停顿时间(如100ms-500ms) 的场景。
- 适合需要消除内存碎片,避免长时间Full GC的应用。
-
超越G1:
- 如果延迟要求极高(<10ms),或者堆内存极大(>100GB),应优先考虑 ZGC(JDK 11+) 或 Shenandoah(JDK 12+)。
CMS是追求低延迟的“先驱”,但受困于内存碎片和Full GC风险;G1是更均衡的“后继者”,通过分区回收和停顿预测,在延迟与吞吐量之间取得了更好的平衡,并已成为现代Java应用的主流选择。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播