写点什么

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

发布于: 2021 年 04 月 20 日

​​摘要:知道三色标记吗?是红黄蓝三色标记吗?


本文分享自华为云社区《从三色标记说开去》,原文作者: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.csdn.net/xingkongjuhao/article/details/101801460


点击关注,第一时间了解华为云新鲜技术~

发布于: 2021 年 04 月 20 日阅读数: 25
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
三色标记原理,我给应聘者问懵了...