CMS收集器的主要设计目标是:低应用停顿时间。它通过两种方式实现这一目标:
- 不压缩老年代,而是使用空闲列表来管理回收空间。
- 大部分标记清理工作与应用程序并发执行。
主要问题:由于不压缩带来的老年代堆碎片,或者在对象分配率高的情况下,都可能导致Full GC。
CMS收集器的GC周期主要由7个阶段组成,其中有两个阶段会发生stop-the-world,其他阶段都是并发执行的。(亦有4个阶段、6个阶段等说法)
Phase 1: Initial Mark(初始化标记)
初始化标记阶段,是CMS GC的第一个阶段,也是标记阶段的开始。主要工作是标记可直达的存活对象。
主要标记过程
- 从GC Roots遍历可直达的老年代对象;
- 遍历被新生代存活对象所引用的老年代对象。
程序执行情况
- 支持单线程或并行标记。
- 发生stop-the-world,暂停所有应用线程。
(Marked obj:老年代绿色圆点表示被初始化标记的对象。)
Phase 2: Concurrent Mark(并发标记)
并发标记阶段,是CMS GC的第二个阶段。
在该阶段,GC线程和应用线程将并发执行。也就是说,在第一个阶段(Initial Mark)被暂停的应用线程将恢复运行。
并发标记阶段的主要工作是,通过遍历第一个阶段(Initial Mark)标记出来的存活对象,继续递归遍历老年代,并标记可直接或间接到达的所有老年代存活对象。
(Current obj:该对象的引用关系发生变化,对下一个对象的引用被删除。)
由于在并发标记阶段,应用线程和GC线程是并发执行的,因此可能产生新的对象或对象关系发生变化,例如:
- 新生代的对象晋升到老年代;
- 直接在老年代分配对象;
- 老年代对象的引用关系发生变更;
- 等等。
对于这些对象,需要重新标记以防止被遗漏。为了提高重新标记的效率,本阶段会把这些发生变化的对象所在的Card标识为Dirty,这样后续就只需要扫描这些Dirty Card的对象,从而避免扫描整个老年代。
Phase 3: Concurrent Preclean(并发预清理)
在并发预清洗阶段,将会重新扫描前一个阶段标记的Dirty对象,并标记被Dirty对象直接或间接引用的对象,然后清除Card标识。
标记被Dirty对象直接或间接引用的对象:
清除Dirty对象的Card标识:
Phase 4: Concurrent Abortable Preclean(可中止的并发预清理)
本阶段尽可能承担更多的并发预处理工作,从而减轻在Final Remark阶段的stop-the-world。
在该阶段,主要循环的做两件事:
- 处理 From 和 To 区的对象,标记可达的老年代对象;
- 和上一个阶段一样,扫描处理Dirty Card中的对象。
具体执行多久,取决于许多因素,满足其中一个条件将会中止运行:
- 执行循环次数达到了阈值;
- 执行时间达到了阈值;
- 新生代Eden区的内存使用率达到了阈值。
Phase 5: Final Remark(重新标记)
预清理阶段也是并发执行的,并不一定是所有存活对象都会被标记,因为在并发标记的过程中对象及其引用关系还在不断变化中。
因此,需要有一个stop-the-world的阶段来完成最后的标记工作,这就是重新标记阶段(CMS标记阶段的最后一个阶段)。主要目的是重新扫描之前并发处理阶段的所有残留更新对象。
主要工作:
- 遍历新生代对象,重新标记;(新生代会被分块,多线程扫描)
- 根据GC Roots,重新标记;
- 遍历老年代的Dirty Card,重新标记。这里的Dirty Card,大部分已经在Preclean阶段被处理过了。
Phase 6: Concurrent Sweep(并发清理)
并发清理阶段,主要工作是清理所有未被标记的死亡对象,回收被占用的空间。
Phase 7: Concurrent Reset(并发重置)
并发重置阶段,将清理并恢复在CMS GC过程中的各种状态,重新初始化CMS相关数据结构,为下一个垃圾收集周期做好准备。
参考
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html#concurrent_mark_sweep_cms_collector
https://blogs.oracle.com/poonam/understanding-cms-gc-logs
https://blogs.oracle.com/jonthecollector/the-unspoken-phases-of-cms
https://plumbr.io/handbook/garbage-collection-algorithms-implementations#concurrent-mark-and-sweep
https://www.jianshu.com/p/2a1b2f17d3e4
http://psy-lob-saw.blogspot.com/2014/10/the-jvm-write-barrier-card-marking.html
https://www.cnblogs.com/littleLord/p/5380624.html
转载请注明来源:https://zhanjia.iteye.com/blog/2435266
个人公众号
更多文章,请关注公众号:二进制之路
相关推荐
Java垃圾收集(Garbage Collection, 简称GC)是Java编程中的一项重要特性,它自动管理内存,释放不再使用的对象,避免了程序员手动管理内存可能导致的内存泄露问题。本篇将深入探讨Java中的GC过程。 一、Java内存...
这个源码包"cms-java-源码.zip"显然是针对CMS垃圾收集器的Java实现进行的开源分享,旨在帮助开发者深入理解CMS的工作原理及其在Java中的实现细节。 CMS垃圾收集器的主要特点是并发性和低停顿时间。它主要分为四个...
Java程序员在进行内存管理时,垃圾收集(Garbage Collection, GC)是一个不可或缺的部分。理解GC的工作原理对于优化程序性能、防止内存泄漏以及提高系统稳定性至关重要。这篇文章将深入探讨Java中的垃圾收集机制,...
Java 7 GC(垃圾回收)参数配置是Java虚拟机(JVM)调优的关键组成部分,它决定了垃圾回收的行为和性能表现。本文将详细介绍Java 7中常见的垃圾回收器和相应的JVM参数,帮助读者更好地理解和使用这些参数进行性能...
如果这个阶段耗时过长,CMS收集器会中断它,转而触发一次Full GC,以确保垃圾收集的效率。 5. 并发重置(CMS-concurrent-reset):这个阶段会重置CMS收集器的状态,为下一次垃圾收集做好准备。 CMS收集器的一个...
Java GC主要分为几个阶段:标记、扫描、压缩和清理。标记阶段是找出所有存活的对象;扫描阶段确定哪些对象是可达的,哪些是不可达的;压缩阶段是为了整理内存,将存活的对象移动到一起,消除碎片;最后的清理阶段则...
JVM 和 GC 相关参数、问题解决过程、排除应用程序的内存使用问题、排除 Cache 内容过多的问题、调整 GC 时间点、调整对象在年轻代内存中驻留的时间、CMS Remark之前强制进行年轻代的 GC 等几个方面详细介绍Java服务...
Java垃圾回收(GC)机制是Java编程语言中的一个重要特性,它自动管理程序的内存空间,负责识别并清除不再使用的对象,以防止内存泄漏。本文将深入探讨Java GC的工作原理、类型、过程以及优化策略。 一、Java垃圾...
3. **GC策略与调优**:Java提供了多种GC算法,如Serial、Parallel、Concurrent Mark Sweep (CMS) 和 Garbage First (G1)。每种策略都有其适用场景和优缺点。例如,G1适合大内存、低延迟的应用,而CMS则在内存较小、...
Java的垃圾收集(Garbage Collection, GC)机制是Java编程语言的一个重要特性,它自动管理内存,使得程序员无需手动释放不再使用的对象,从而避免了内存泄漏等问题。在深入理解Java的GC机制之前,我们首先要知道Java...
在初始和最终标记阶段,GC会暂停应用,但这两个阶段通常非常快。并发标记和并发清除阶段,GC与应用程序线程并发执行,显著降低了整体的暂停时间。 CMS的一个关键特性是它的低停顿时间,这得益于其并发执行的特性。...
- CMS(Concurrent Mark Sweep)GC:强调低延迟,采用并发标记和并发清除阶段,尽可能减少应用程序暂停时间。 - G1(Garbage First)GC:面向服务端,目标是预测并控制垃圾回收停顿时间,实现低延迟。 了解这些基本...
在CMS的工作流程中,包含了以下几个关键阶段: 1. **初始标记(Initial Marking)**:这是一个Stop the World事件,它快速地标记出所有GC Roots可以直接达到的对象。GC Roots通常包括虚拟机栈中的引用(栈帧的本地...
Java 8 GC(垃圾收集)速查表是一个非常有价值的资源,尤其对于那些在JVM(Java虚拟机)调优方面工作的开发人员来说。这个压缩包包含了一张名为"Java 8 - GC cheatsheet.png"的图片,它概述了Java 8中关于垃圾收集的...
Java的自动垃圾收集机制可以分为两个阶段:标记阶段和清理阶段。在标记阶段,JVM会标记出所有的垃圾对象,然后在清理阶段,JVM会释放这些垃圾对象所占用的内存。 Java垃圾收集处理方法的优点是可以提高程序的可靠性...
为避免以上两种状况引起的 Full GC,调优时应尽量做到让对象在 Minor GC 阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。 永生区空间不足 JVM 规范中运行时数据区域中的方法区,在 HotSpot ...
Java的垃圾收集器(Garbage Collector,简称GC)是Java平台的一个重要特性,它负责自动管理程序中的内存,避免手动内存管理可能导致的内存泄漏问题。Java的垃圾收集机制是基于引用计数和可达性分析算法的,其目标是...
这个日志显示了CMS收集器在处理年轻代的Minor GC和老年代的初始标记阶段的情况。 在多核机器上,CMS收集器可以配置为使用一定数量的线程,通常是物理核心数的四分之一,以提高并发效率。然而,CMS在单核环境下可能...