【一道面试题】讲一讲JVM中的三色标记法?
admin
2024-05-10 21:29:21

所谓三色标记法,是GC在进行垃圾回收前,对哪些对象需要进行回收、哪些对象不需要进行回收的一种标记方式,便于垃圾回收器进行垃圾回收。

三色标记法将对象的颜色分为:

  • 白色:该对象尚未被标记(不可达的对象,也就是需要进行垃圾回收的对象)
  • 灰色:该对象已经被标记,但是该对象引用的对象正在标记中(该对象不会被垃圾回收,但是要通过该对象的引用来进行可达性分析)
  • 黑色:该对象,包括该对象引用的对象都已经被标记过了(该对象不会被垃圾回收)

三色标记法在实际中会结合可达性分析算法来使用,具体流程如下:

  • 首先创建三个集合:白、灰、黑
  • 将所有对象放入白色集合中
  • 然后从GCRoots开始遍历所有对象,把遍历到的对象从白色集合放入灰色集合
  • 之后遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合
  • 重复上一步操作直到灰色中无任何对象
  • 如果检测到对象发生了变化,则会重复以上操作
  • 清除所有白色对象

这里还会引申出一个问题,三色标记法中的并发漏标问题是怎么处理的?在讲这个问题前,首先讲一讲为什么会出现并发漏标问题:

在早期的垃圾回收器中,用户线程和垃圾回收线程是不能并发执行的,只要垃圾回收线程在运行,那么用户线程就得暂停,这也就是所谓的Stop The World,那么这样肯定是不行的,所以现在的垃圾回收器都在朝着并发执行的方向做努力 ,现有的垃圾回收器可以在垃圾回收的某些阶段实现并发,比如在对老年代的对象进行标记时,不会阻塞用户线程,但是这样也就带来了一个新的问题,即并发漏标问题,所谓的并发漏标问题简单来说就是,用户线程在垃圾回收器工作时修改了某个对象引用带来的问题,常见场景如下:

  • 第一个场景,假设A对象引用了B对象,B对象又引用了C对象,垃圾回收器在运行时,首先将A对象标记为黑色,然后开始标记B对象,假设此时用户线程切断了B对象与C对象之间的引用关系,那么对于正在标记B对象的垃圾回收器而言,由于此时B对象已经与C对象断开了关系,那么垃圾回收器将无法遍历到C对象,那么它会将C对象当成是白色垃圾,那么假设此时用户线程又让A对象引用了C对象,由于此时B对象已经被标记为黑色了,垃圾回收器就不会再去管B对象了,那么就会出现这样一个问题,就是B对象需要引用的对象被垃圾回收器当成了垃圾,这样也就出现了漏标问题。
  • 第二个场景,假设此时存在A对象和B对象,两者之间暂时没有引用关系,且B对象不可达,也就是说B对象此时在垃圾回收器眼中属于一个应该被回收的垃圾,那么假设此时垃圾回收器标记完了A对象,然后用户线程让A对象引用了B对象,那么由于A对象已经被标记为黑色了,垃圾回收器也不会再去管A对象了,那么也就出现了漏标问题

那么漏标问题是如何解决的呢?CMS 垃圾回收器和 G1 垃圾回收器给出了不同的解决方案

增量更新法(Incremental Update )

CMS垃圾回收器采用的解决方案,主要思路是,将整个标记过程分为两个阶段,一是并发标记阶段,二是重新标记阶段,在并发标记阶段,还是会使用三色标记法对所有可达对象进行标记,但是区别在于,一旦这些对象发生赋值动作时就会被拦截,如果该对象是黑色的,就会将其标记为灰色,当所有标记完成后,就会Stop The World,进入重新标记阶段,然后再对这些灰色的对象进行处理。

这种方案并不能完全避免漏标问题,如果一个灰色对象已经被标记的属性指向了一个白色对象,垃圾回收器拦截赋值动作时发现该对象是灰色对象,则并不会对其进行处理,那么当这个对象所有的属性被标记结束后,由灰色变成了黑色,那么这个对象引用的白色对象就无法被标记,进而漏标

SATB(Snapshot At The Beginning)原始快照法

G1垃圾回收器采用的解决方案,同样是将整个标记过程分成并发标记和重新标记两个阶段,在并发标记阶段,会将所有被断开的引用或者新增的引用记录下来,此时这些引用在垃圾回收器眼中是白色的,在所有标记结束后,会Stop The World,然后在重新标记阶段扫描这些白色的对象,检查其是否被引用,若未被引用则直接回收,若被引用了则标记为黑色

相关内容

热门资讯

敦煌壁画的守护人--敦煌戈徒旅... 昨天刷抖音本来是想随便打发下时间,结果一个“穿越千年的敦煌色彩”的视频直接把我钉在原地,越看越入迷,...
湖南红色旅游主题口号及形象标识... 近日,由湖南省文化和旅游厅主办的湖南红色旅游主题口号及形象标识(LOGO)征集活动圆满结束,获奖作者...
2024年山西省旅游业大数据报... 今天分享的是:2024年山西省旅游业大数据报告 报告共计:20页 2024年山西省旅游业实现高质量增...
中国跻身南极第二大客源国,深圳... 深圳商报·读创客户端记者 范宏韬 11月18日,俞敏洪一连发布10条南极旅行视频,从穿越德雷克海峡到...
螺髻山温泉撷影 螺髻山温泉位于四川省凉山彝族自治州普格县螺髻山镇,该景区是我国山地中极为罕见且保存完好的第四纪古冰川...