关于后端:深入浅出JVM十六之三色标记法与并发可达性分析

33次阅读

共计 2237 个字符,预计需要花费 6 分钟才能阅读完成。

上篇文章深入浅出 JVM(十五)之垃圾回收器(上篇)介绍性能指标吞吐量和提早、串行收集器、并行收集器以及吞吐量优先收集器

为了更好的形容并发垃圾收集器,本篇文章将先深入浅出的介绍三色标记法以及并发可达性剖析遇到的问题以及解决方案

三色标记法

JVM 中应用可达性剖析算法来判断对象是否持续应用

当对象不可达时,执行过 finalize 办法或者 finalize 办法搭不上援用链时能力回收这些对象

不了解如何判断对象不再应用的同学能够看这篇文章深入浅出 JVM(十一)之如何判断对象“已死”

为了更好的阐明并发可达性剖析,咱们应用三色标记法模仿,先阐明三色标记法

三色标记法的色彩、流程阐明

三色标记法的三种色彩阐明

彩色:以后对象被扫描过,并且它援用的对象也被扫描

灰色:以后对象被扫描过,至多有一个援用未被扫描

红色:以后对象未被扫描过

GC 根节点总是彩色的,因为它们隐式可达

扫描时,从 GC Roots 节点(灰色)开始,将它援用的对象全染成灰色,再将本人染成彩色,再从灰色对象汇合中遍历上述操作,相似树的层序遍历

当扫描结束时,如果对象仍旧是红色阐明这个对象是不可达对象

比方图中的 a 变成彩色,阐明 a 援用的对象 b 曾经被扫描了;而 b 是灰色,阐明 b 至多有一个援用的对象没被扫描(b 援用的 c 就还未被扫描)

b 将援用的 c 染成灰色后,将本人染成彩色,再从灰色对象汇合中取出对象 c 进行后续操作

并发可达性剖析

当 GC、用户线程并发执行时,就会呈现对象援用可能扭转的状况,可能造成 浮动垃圾和对象失落 的状况

浮动垃圾

一种状况会把本来死亡的对象改成活的对象,成为浮动垃圾,下次再回收掉

比方 c 将援用的 d、e 染成灰色后将本人染成彩色

因为还未扫描完结,用户线程将 c 援用 e 删除了c.e = null,原本 e 没有被援用应该变成垃圾

但因为并发执行,后续 GC 线程从灰色对象汇合中获取 d、e 进行解决,最终会被染黑,e 就变成浮动垃圾,本轮 GC 不会回收 e

浮动垃圾的呈现能够被承受,本轮不 GC,下次 GC 也会进行回收

对象失落

另一种状况会把本来存活的对象变成死亡的对象从而进行回收,非常危险

在从灰色对象拿出对象 c 解决前,用户线程将 c 援用 e 删除c.e = null,后续 c 就不会将 e 染成灰色,只将 d 染成灰色

解决完对象 c 后,用户线程批改援用,让对象 b 援用对象 e b.e = e,对象 e 变成须要应用的对象,但最终解决完 d 后,对象 c 仍旧是红色

这种状况下就会产生对象失落,对象 c 可能被 GC 回收,这种状况是危险的,不容许呈现

通过钻研表明对象隐没须要满足的条件:

  1. 插入一条或多条从彩色对象到红色对象的新援用
  2. 删除全副从灰色对象到该红色对象的间接或间接援用

只须要毁坏其中一条就能够防止对象隐没

增量更新和原始快照 别离毁坏条件 1、2

增量更新和原始快照会借助写屏障来解决,写屏障能够了解成 AOP(在执行外围办法的前、后能够执行其余操作)

 // 写前屏障解决
 // 执行外围办法
 // 写后屏障解决

增量更新

增量更新应用写后屏障,某个对象新增的援用时,将该对象记录下来,扫描完后将这个对象变为灰色对象从新扫描,在后续这个从新扫描的阶段须要用户线程 STW

应用从新扫描,短暂 STW 的形式毁坏条件一

用下面那张对象失落的图举例的话,就是 b 对象在新增 e 援用时,后续会将 b 对象变为灰色从新扫描

从新扫描后,e 对象最终也染黑

原始快照

原始快照应用写前屏障,在删除援用前保留要删除的援用,在扫描结束后将这些删除的援用变为灰色对象从新扫描

原始快照毁坏条件二,将红色对象变为灰色

并且GC 开始后产生新增援用时,应用 TAMS(Top at Mark Start)指针对新增援用进行记录(隐式可达)

对象 c 删除援用的对象 e 时记录对象 e,扫描结束时如下

STW 从新扫描时,会将记录的对象 e 变灰色从新扫描,对象 e 变成了浮动垃圾;而新增的对象 g 用 TAMS 指针隐式可达间接变黑

因为被删除援用变灰,它可能变成浮动垃圾

总结

本篇文章围绕并发的可达性剖析深入浅出的解析三色标记法、并发可达性剖析可能呈现的浮动垃圾,对象失落问题以及解决对象失落问题的增量更新、原始快照两种形式

在三色标记法中,彩色代表曾经扫描实现、灰色代表至多有一个援用未扫描、红色代表还未扫描,GC 根节点默认彩色隐式可达

三色标记法从 GC 根节点开始将援用对象变成灰色并放入灰色汇合,并将本人变成彩色,接着再从灰色汇合中取出下一个对象进行解决,直到灰色汇合为空,还是红色的对象就是不可达对象

用户、GC 线程并发执行时,可能扭转对象的援用关系,可能造成浮动垃圾、对象隐没的问题;浮动垃圾能够承受,下次 GC 会进行回收,然而对象隐没是不能承受的

对象隐没产生的两个条件是彩色对象新增到红色对象的援用和删除所有灰色对象到红色对象的间接 / 间接援用

增量更新应用写后屏障毁坏条件一,记录新增红色对象援用的彩色对象,扫描结束后 STW 将这个彩色对象变为灰色对象从新扫描

原始快照应用写前屏障毁坏条件二,记录被删除的红色对象,应用 TAMS 指针让新增援用隐式可达,扫描完笔后 STW 将记录的红色对象变成灰色对象从新扫描,并且将隐式可达的对象变黑

最初(一键三连求求拉~)

本篇文章将被支出 JVM 专栏,感觉不错感兴趣的同学能够珍藏专栏哟~

本篇文章笔记以及案例被支出 gitee-StudyJava、github-StudyJava 感兴趣的同学能够 stat 下继续关注喔 \~

有什么问题能够在评论区交换,如果感觉菜菜写的不错,能够点赞、关注、珍藏反对一下 \~

关注菜菜,分享更多干货,公众号:菜菜的后端私房菜

本文由博客一文多发平台 OpenWrite 公布!

正文完
 0