CMS收集器和G1收集器的区别?
2 个回答
世界上没有快乐的地方,只有快乐的人。李寒衣CMS(Concurrent Mark-Sweep)和G1(Garbage First)都是Java虚拟机的垃圾收集器,它们各自有不同的设计理念、适用场景以及回收机制。下面详细对比这两者的区别。 ### 1. **设计目标** - **CMS 收集器**: - **低延迟**:CMS 的主要目标是尽量减少老年代的垃圾收集导致的停顿时间,因此适合那些对响应时间要求较高的应用程序,如互联网应用或对延迟敏感的系统。 - **并发执行**:CMS 在大多数阶段会与应用线程并发工作,减少了 Stop-The-World(STW)暂停的时间。 - **G1 收集器**: - **区域化管理内存**:G1 是为了替代 CMS 而设计的,它的目标是既能提供低延迟,又能避免 CMS 的内存碎片化问题。 - **可预测的暂停时间**:G1 可以让用户设置预期的最大暂停时间,并根据这个目标动态调整垃圾回收的行为。 - **针对大堆内存**:G1 能够处理大堆内存(数 GB 到数十 GB 甚至更大),而 CMS 在大堆内存下表现不佳。 ### 2. **内存布局** - **CMS 收集器**: - **分代收集**:CMS 基于经典的分代收集机制,将堆内存分为**新生代**和**老年代**。新生代使用 **复制算法**,老年代使用 **标记-清除算法**。 - **碎片化问题**:由于 CMS 采用标记-清除算法,它会导致老年代内存碎片化,进而可能引发 `Concurrent Mode Failure`,并导致 Full GC 的长时间暂停。 - **G1 收集器**: - **区域化收集(Region-based Collection)**:G1 将堆划分为许多大小相等的**内存区域(Region)**,每个区域可以作为 Eden、Survivor 或老年代的一部分。相比传统的分代收集,G1 更灵活地管理内存。 - **减少碎片**:G1 使用**标记-整理算法**,不仅回收垃圾,还会整理内存,减少碎片,使得老年代内存更加紧凑。 ### 3. **垃圾收集算法** - **CMS 收集器**: - **标记-清除算法**:CMS 使用的是标记-清除算法,标记出存活对象,直接清除垃圾对象。但它不会移动对象,因此会导致内存碎片。 - **并发收集**:CMS 与应用线程并发进行标记和清除,只有在初始标记和重新标记阶段会短暂暂停(STW)。 - **Full GC**:当出现内存碎片或并发收集失败时,CMS 会触发一次 Full GC,这会导致长时间的暂停。 - **G1 收集器**: - **标记-整理算法**:G1 使用标记-整理算法,不仅标记存活对象,还会整理内存,避免内存碎片化。它会定期整理老年代的对象,将它们移动到连续的内存区域。 - **分区化的垃圾优先回收(Garbage First)**:G1 会优先回收那些垃圾最多的区域(Region),提高回收效率,避免老年代频繁的 Full GC。 - **混合回收**:G1 可以同时回收新生代和老年代,并且通过预测分析决定要回收哪些区域,从而达到最优的回收效率。 ### 4. **暂停时间预测** - **CMS 收集器**: - **暂停不可预测**:CMS 的暂停时间取决于对象的数量和老年代的情况,尤其是在内存碎片严重时可能会出现长时间的 Full GC 停顿。 - **G1 收集器**: - **可预测的暂停时间**:G1 允许用户通过 `-XX:MaxGCPauseMillis` 参数设定期望的最大垃圾回收暂停时间。G1 会根据这个目标动态调整垃圾回收的频率和回收的内存区域,尽量使垃圾收集器的停顿时间在设定范围内。 ### 5. **适用场景** - **CMS 收集器**: - 适用于 **低延迟**、对响应时间敏感的应用,尤其是那些堆内存不是特别大的应用场景(通常在 4GB~16GB 之间)。 - CMS 在大堆内存环境下表现不佳,因为它会引发频繁的 Full GC。 - **G1 收集器**: - 适用于 **大堆内存**,如大规模服务器应用,支持大于 16GB 的堆内存,甚至数百 GB 的堆。 - G1 提供可控的暂停时间,适合对垃圾回收有明确暂停时间要求的大型应用。 ### 6. **内存碎片化** - **CMS 收集器**: - 由于使用标记-清除算法,CMS 不会对内存进行压缩整理,老年代容易产生**内存碎片**,最终可能导致无法分配大对象。 - **G1 收集器**: - 使用标记-整理算法,G1 会在回收时对内存进行整理,减少内存碎片。 ### 7. **生命周期** - **CMS 收集器**: - CMS 早已不再是 Oracle 官方推荐的垃圾收集器。自 JDK 9 开始,CMS 被标记为**弃用(Deprecated)**,并在之后的 JDK 版本中逐渐被 G1 取代。 - **G1 收集器**: - G1 被 Oracle 官方推荐为替代 CMS 的垃圾收集器,并在 JDK 9 及以上版本成为默认垃圾收集器。 ### 总结 | 特性 | CMS 收集器 | G1 收集器 | |---------------------------|--------------------------------|------------------------------| | 设计目标 | 低延迟,减少暂停 | 可预测的暂停时间,适合大堆内存| | 内存布局 | 分代收集,新生代/老年代 | 区域化收集,Region | | 垃圾回收算法 | 标记-清除,容易碎片化 | 标记-整理,减少内存碎片 | | 暂停时间 | 不可预测,可能会出现 Full GC | 可预测,通过 MaxGCPauseMillis | | 并发性 | 并发标记和清除 | 并发标记和整理 | | 内存碎片 | 容易产生内存碎片 | 减少内存碎片 | | 适用场景 | 低延迟应用,堆内存较小 | 大堆内存,暂停时间敏感应用 | | 生命周期 | 已弃用,JDK 9 后不再推荐使用 | 默认垃圾收集器,JDK 9+ | 总体来说,**G1** 是 CMS 的现代化替代方案,解决了 CMS 的许多局限性,如内存碎片和不可预测的 Full GC 停顿,同时提供了更高效的内存管理机制和暂停时间的可预测性。发布于 2024-06-29 15:01 •IP属地 浙江举报评论收藏
希望有人告诉你开心比对错更重要。梅拾璎1. CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用; 2. G1收集器收集范围是老年代和新生代,不需要结合其他收集器使用; 3. CMS收集器以最小的停顿时间为目标的收集器; 4. G1收集器可预测垃圾回收的停顿时间 5. CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片 6. G1收集器使用的是“标记-整理”算法,进行了空间整合,降低了内存空间碎片。发布于 2022-03-26 04:21 •IP属地 重庆举报评论收藏
公众号进入网站体验更佳

