面试官:咱们今天就浅谈JVM三色标记法,我:这也问?

开发 前端
三色标记算法是根可达算法的一种实现方案,其目的是为了找出所有可达对象。三色标记算法会产生多标和漏标问题,其中漏标问题最严重。漏标问题会导致本该存活的对象被回收,从而导致严重的程序问题。

1.前言

三色标记算法,用于垃圾回收器升级,将STW变为并发标记。STW就是在标记垃圾的时候,必须暂停程序,而使用并发标记,就是程序一边运行,一边标记垃圾。

2. 三色标记算法

2.1.什么是三色:

首先我们需要知道三色标记法就是根据可达性分析,从GC Roots开始进行遍历访问,在遍历对象过程中,按“是否检查过”这个条件将对象标记成三种颜色:

  • 黑色: 代表对象已经检查过,且成员对象也被检查过了。如果有其他对象引用指向了黑色对象,无须重新检查一遍。黑色对象不可能直接(不经过灰色对象)指向某个白色对象。
  • 灰色代表对象已经检查过,但成员还没全部检查完成
  • 白色代表对象没有被检查。 在可达性分析刚刚开始的阶段, 所有的对象都是白色的, 若在分析结束的阶段, 仍然是白色的对象, 即代表不可达。

2.2.三色标记过程:

假设现在有白、灰、黑三个集合(表示当前对象的颜色),其遍历访问过程为:

  1. 初始时,所有对象都在【白色集合】中;
  2. 将 GC Roots直接引用到的对象挪到【灰色集合】中;
  3. 从灰色集合中获取对象:

3.1. 将本对象引用到的其他对象全部挪到【灰色集合】中;

3.2. 将本对象挪到【黑色集合】里面。

  1. 重复步骤3,直至【灰色集合】为空时结束。
  2. 结束后,仍在【白色集合】的对象即为GC Roots不可达,可以进行回收。

需要注意,传统标记方式发生Stop The World时,对象间的引用是不会发生变化的,可以轻松完成标记。

而并发标记在标记期间应用线程还在继续跑,对象间的引用可能发生变化,就会出现错标和漏标的情况就有可能发生。

3.存在的问题

3.1.浮动垃圾:标记过不是垃圾的,变成了垃圾

并发标记的过程中,若一个已经被标记成黑色或者灰色的对象,突然变成了垃圾,此时,此对象不是白色的不会被清除,重新标记也不能从GC Root中去找到,所以成为了浮动垃圾,这种情况对系统的影响不大,留给下一次GC进行处理即可。

3.2.对象漏标问题:需要的对象被回收

并发标记的过程中,一个业务线程将一个未被扫描过的白色对象断开引用成为垃圾(删除引用),同时黑色对象引用了该对象(增加引用)(这两部可以不分先后顺序);

因为黑色对象的含义为其属性都已经被标记过了,重新标记也不会从黑色对象中去找,导致该对象被程序所需要,却又要被GC回收,此问题会导致系统出现问题。

4.总结

三色标记算法是根可达算法的一种实现方案,其目的是为了找出所有可达对象。三色标记算法会产生多标和漏标问题,其中漏标问题最严重。漏标问题会导致本该存活的对象被回收,从而导致严重的程序问题。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2023-01-08 13:46:49

2021-08-16 10:35:52

JVM标记法屏障

2021-08-06 11:46:46

Go三色标记法

2020-07-09 15:45:22

GoGC内存

2022-11-04 08:47:52

底层算法数据

2022-08-15 08:01:00

三色标记JVM算法

2023-03-15 09:49:00

CMSG1三色标

2021-05-11 21:56:11

算法清除JVM

2021-03-24 10:25:24

优化VUE性能

2021-12-25 22:31:10

MarkWord面试synchronize

2021-11-08 09:18:01

CAS面试场景

2021-12-02 08:19:06

MVCC面试数据库

2024-03-07 17:21:12

HotSpotJVMHot Code

2010-08-23 15:06:52

发问

2021-12-16 18:38:13

面试Synchronize

2021-01-06 05:36:25

拉链表数仓数据

2018-04-23 11:00:44

PythonRedisNoSQL

2022-01-05 09:55:26

asynawait前端

2023-02-16 07:30:38

引用计数算法

2022-01-20 10:34:49

JVM垃圾回收算法
点赞
收藏

51CTO技术栈公众号