💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
### CMS将可达性分析分解成两个阶段 a.仅扫描与根节点直接关联的对象; b.继续向下扫描完所有对象。因此,标记阶段也被拆分成两个阶段,即初始标记和并发标记。 #### CMS完整的收集过程如下: 1. 初始标记(init-mark):仅扫描与根节点直接关联的对象并标记,这个阶段必须STW, 由于跟节点数量有限,所以这个过程非常短暂。 2. 并发标记(concurrent-marking):与用户线程并发标记。这个阶段在初始标记的基础上继续向下追溯标记。在并发标记阶段,用户线程和标记线程并发执行,所以用户不会感受到停顿。 3. 并发预清理(concurrent-precleaning):与用户线程并发进行。在并发标记阶段一些对象的引用已经发生了变化,precleaning会发现这些引用关系的改变,并将存活的对象标记。举个例子:如果线程A有一个指向对象X的引用,并将该引用传递给了线程B,CMS需要记录下线程B持有了对象X,即使线程A已经不存在了。precleaning是为了减少下一阶段“重新标记”的工作量,因为remark阶段会STW。 4. 重新标记(remark): remark阶段会STW。如果应用正在并发运行且在不断地改变对象引用,CMS则不能准确地确定某个对象是否存活。所以CMS会在remark阶段STW,从而获取所有引用关系的改变。 5. 并发清理(concurrent-sweeping):清理垃圾对象,这个阶段GC线程和用户线程并发执行。 6. 并发重置(concurrent-reset):重置CMS收集器的数据结构,做好下一次执行GC任务的准备工作。 ![](https://img.kancloud.cn/b9/b4/b9b40bfc57d6253c4d9a3c3d7cc1c79e_1090x323.png) 由上述CMS执行过程可以得出: * **CMS两次STW的时间都是比较短暂的,两个最耗时的时间是并发标记和并发清理,但是这两个阶段都是可以和用户线程并发执行的**。 * 由于在并发标记和并发清理阶段用户线程并没有中断,所在CMS回收过程中,还应该保证用户线程有足够的内存可用,**CMS并不能让其他老年代垃圾回收器那样等到内存几乎被填满之后再进行垃圾回收**。而是当堆内存使用率达到一定的阈值的时候就开始进行回收,以确保应用程序在CMS执行垃圾回收期间依然有足够的内存空间支持运行。 * 如果**CMS垃圾回收执行失败(CMS运行期间预留的内存无法满足程序需要,会出现Concurrent Mode Failure),这是JVM将要启动后备方案,临时启动Serial Old收集器重新进行老年代垃圾回收**。