三色标记原理,我给应聘者问懵了...

本文分享自华为云社区《从三色标记说开去》,原文作者:java初中生。

【1】关于三色标记

前几天,公司临时派我去面试一个java实习生,由于没有这方面的任何经验,于是一不小心,我就问超纲了。

问过了java基础,我随口又问了一句,知道三色标记吗?

他显然是懵逼了一瞬间,但也仅仅一瞬间,然后振振有词地反问,是红黄蓝三色标记吗?

这倒是反把我问住了。

面试有问题答不出来,这其实可以理解,不懂就说不懂,不会就说不会,子曾经曰过,知之为知之。

三色标记,正经来说,就只有黑白灰三个颜色。

但实际上,三色标记,和颜色其实没有任何关系,只与一次扫描状态相关

  • 黑色节点,代表根节点或者已扫描完的节点,该节点的子节点也被扫描完;
  • 灰色节点,代表已扫描完的节点,该节点的子节点存在未被扫描的情况;
  • 白色节点,代表未被扫描的节点。
三色标记原理,我给应聘者问懵了...

上图中,A就是黑色节点,B为灰色,因为B的子节点C未被扫描,C则是白色节点。

如果,扫描结束,C依旧是白色,则C被回收。

但这里会存在一个问题,如果在上图的情况下,BC的引用断掉,而AC的引用被建立,如下图:

三色标记原理,我给应聘者问懵了...

则会出现以下情况:

  • B扫描完,无引用,变黑。
  • C,按道理说,也会变灰,然后变黑。
  • 但A此时已经是黑色节点,则不会扫描其引用,所以C不会被扫描,还是白色。
  • 最后,C会被当垃圾回收。

这显然是一个误操作,因为C当前是根可达的,那该问题怎么办呢?

常用的垃圾回收器,CMS和G1都给出了解决方案。

CMS的方法叫做Incremental Update算法。

该算法从结果入手,判断扫描完结时,是否有白色对象被黑色对象引用,如果被引用,则通过write barrier写屏障技术,把黑色的对象重新标记为灰色,然后重新扫描。

三色标记原理,我给应聘者问懵了...

G1的方法叫做SATB算法。

该算法从源头入手,GC开始之前拍摄快照,设定所有存在引用的对象,都是存活的。

GC扫描之后,再次拍摄快照,将新引用的存活对象标记。

然后将快照叠加。

三色标记原理,我给应聘者问懵了...

这样,C显示的是被A,B两个对象引用。

但这样会有一个弊端,如果此时,AC之间的引用没有被建立,则C本来应该被回收,但此轮却并没有被回收。

【2】跨代引用的问题

跨代引用这个概念被提出来的时候,很多人都有似曾相识的感觉。但具体要说,很多人就说不出所以然来了。

其实,java堆说到底就两个代(年轻代和老年代),持久代在jdk的某个版本后,就被放到本地方法栈了。

跨代引用,即父节点在一个代,而引用对象在另一个代。

一般来说,父节点都在老年代,引用对象在年轻代。

三色标记原理,我给应聘者问懵了...

如上图,X引用和Y引用都是属于跨代引用。

跨代引用一般多发生在G1回收器中,因为G1的内存采用分块的模式,内存区域不稳定

那么,年轻代回收(young GC)时,是否要根据可达性分析,遍历所有的老年代关联,直到根节点呢。

不需要。

只要父节点在老年代,则一律视为根节点。

在这里(跨代引用)要引入两个概念,结果集和卡表。卡表可以看作一个老年代分区的集合或者数组,如下图。

三色标记原理,我给应聘者问懵了...

结果集,就是一组类似于map的容器,key存放卡表的下标,value存放引用关系

三色标记原理,我给应聘者问懵了...

想想这样做的好处是什么?

【3】安全点和安全区域

java工作线程和垃圾回收线程,一般情况下,是不能同时进行的。

通常老师讲到这个问题的时候,会打个比方:吃饭和洗碗擦桌子。

之所以工作线程和垃圾回收线程不能同时进行,是因为人不能一边吃饭一边收拾碗筷(触手怪除外)。

同理,还有一个问题,你也不能把饭吃到一半,把碗拿过去洗。

所以,你必须在吃完饭的时候,洗碗。

吃完饭的这个时间,就是安全点。

一般来说,安全点是某个线程的结束或者中断的时间,可以是方法调用,循环跳转,异常跳转等。

再回头说说垃圾回收的全过程。

  • 业务线程执行过程中,会不断轮询一个标志位,该标志位处于垃圾回收线程中;
  • 如果需要做垃圾回收,回收线程会将标志位改掉;
  • 业务线程收到标志位信息,会走到安全点,然后停止;
  • 垃圾回收线程启动,回收垃圾。

三色标记原理,我给应聘者问懵了...

那么,安全区域是什么呢?

一个区域所有的点都是安全点,这一部分就是安全区域。

还是拿原来那个例子,如果你晚上减肥,不想吃饭,碗什么的,随时都可以洗。

【4】如何查看GC日志

直接上命令:-XX+PrintGCDetails。

该命令可以在控制台打印GC日志。

日志内容如下:

三色标记原理,我给应聘者问懵了...

【5】终:垃圾回收各指标

吞吐量:指在应用程序的生命周期内,应用程序所花费的时间和系统总运行时间的比值。

公式:吞吐量=系统应用时间/系统总运行时间

垃圾回收器负载:和吞吐量正好相反,垃圾回收器负载指垃圾回收器耗时与系统运行总时间的比值。

公式:吞吐量=垃圾回收时间/系统总运行时间

停顿时间(延迟):指垃圾回收器正在运行时,应用程序的暂停时间。

PS:独占回收器延迟长,但吞吐量高,并发回收器,延迟少,但吞吐量低。

垃圾回收频率:指垃圾回收器多长时间会运行一次。

PS:垃圾回收器的频率应该是越低越好。

反应时间:指当一个对象被称为垃圾后多长时间内,它所占据的内存空间会被释放。

PS:即垃圾回收的周期

over~~

堆分配:不同的垃圾回收器对堆内存的分配方式可能是不同的。一个良好的垃圾收集器应该有一个合理的堆内存区间划分。

本文参考资料:https://blog.点击关注,第一时间了解华为云新鲜技术~

版权声明:玥玥 发表于 2021-04-21 4:54:02。
转载请注明:三色标记原理,我给应聘者问懵了... | 女黑客导航