面试题剖析:讲一讲FullGC的过程,三色标记是什么?

本文深入剖析了CMS垃圾回收器下老年代的FullGC过程,包括初始标记、并发标记、重新标记和并发清理四个阶段,并详细解释了三色标记算法及其可能出现的漏标情况。在并发标记阶段,使用白灰黑三种颜色标记对象,而重新标记阶段若未处理黑色对象的新引用可能导致漏标。此外,文章还讨论了内存溢出的一种情况,即CMS在并发清理阶段因新对象超过老年代内存导致的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试题:讲一讲在使用CMS垃圾回收器的情况下,FullGC也即是老年代GC的过程,存活对象的标记算法是什么,什么时候会出现漏标的情况?

面试题常规回答

面试者一般都是回答:老年代GC是使用了标记整理算法,先从GCRoot出发将存活的对象标记,然后并发清理所有的垃圾对象,最后还会进行内存碎片整理。

三色标记的只知道是白色、灰色和黑色,是一种并发标记算法。
漏标的情况就不太了解了。

面试题深入剖析

这里其实就是全面问了FullGC的过程了。这里我们先看一下CMS的老年代GC阶段:

  1. 初始标记(Stop the World)
  2. 并发标记
  3. 重新标记(Stop the World)
  4. 并发清理

接下来我们一步步分析,首先是第一阶段:

初始标记

初始标记其实就是从静态变量、方法栈内的局部变量出发,去标记这些存活的对象,例如:

public class UsersController {

    private static UsersService usersService = new UsersService();

    public UsersModel get(@PathVariable("id") Integer id, HttpServletRequest request) {
        UsersModel model = new UsersModel();
        model.setId(id);
        return model;
    }
}

这里面的 usersService 这个静态变量和执行到get方法内部的model局部变量都是GC Roots标记的起始。这一阶段是会出现 “Stop the World” 的,但是速度很快,小于毫秒级别,大概是微秒级别。

并发标记

这一阶段会让系统线程同时运行,可以继续创建新对象。垃圾回收线程会尽快对已经识别的存活对象进行追踪。也就是对上面的usersService静态变量和model局部变量查找内部引用了哪些对象、或者被哪些对象引用了。这一阶段最耗时,但是也不会对系统造成卡顿影响,只是占用了CPU资源。

这里的标记算法就是三色标记,即使用白灰黑三种颜色标记对象。白色是未标记;灰色自身被标记,引用的对象未标记;黑色自身与引用对象都已标记。

并发标记

重新标记

因为第二阶段中系统线程会不停地创建新对象和让老对象变成垃圾,所以第三阶段就是进入 “Stop the World”,然后快速将第二阶段中变动的对象进行重新标记。这里有一种情况会出现漏标的现象,产生的条件如下

  1. 黑色对象指向了白色对象。
  2. 灰色对象指向白色对象的引用消失。

漏标的情况

如果在重新标记阶段没有对黑色对象进行重新扫描,则会漏标,因为会把白色D对象当作没有新引用指向从而回收掉。

为了解决漏标问题,CMS 采用增量更新方法,关注引用的增加,增加黑指向白的引用的增加,把黑色重新标记为灰色,下次重新扫描属性。

顺便提一下,G1 采用的是关注引用的删除,记录灰指向白的引用消失,当引用消失的时候要把这个引用推到GC的堆栈,保证白还能被GC扫描到。

并发清理

第四阶段会允许系统线程自由运行,然后由垃圾回收线程来清理之前标记为垃圾的对象。这一阶段比较耗时,但是由于是并发运行的,所以只是占用了CPU资源,不会影响业务系统线程。

最后思考一下:为什么会出现内存溢出的情况?

其中一种情况结合上面的FullGC描述就清楚了,CMS在第二和第四阶段中,业务系统产生的新对象容量一下子超过了老年代的内存大小,导致了CMS无法继续运行,所以就内存溢出了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gemini技术窝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值