主要是记录自己的对马士兵讲的 三色标记法的缺陷 的疑问及最后的理解。对和我有产生同样疑问的人可以参考下。当然也许大家的理解力都比我强,没有和我产生一样的疑问的话可以当看个笑话。
三色标记的概念可以自己看视频或者网上找或者看 文章 ,此处就不在赘述。如果没有先理解三色标记法后面的内容会很难看懂。
首先视频中有两种漏标,疑问点在第二种漏标
第一种漏标:
1.垃圾回收线程
标记完A的所有属性并把A标记为黑色
标记B为灰色。
此时B引用D且D为白色。
2.切换业务线程执行。
让A引用D
去掉B对D的引用
此时D还是白色
3.此时垃圾回收线程继续运行。
由于B不引用D,所以扫描B不会扫描到D
A已经变黑色,所以不会重新扫描A
因此D会漏标。
这种漏标的解决方式是写屏障,就是jvm在让A引用D的时候进行拦截使A重新置为灰色,然后垃圾回收线程继续运行时就会重新扫描A的所有引用,当然会有点浪费性能。
第二种漏标:
图中给的文字已经描述了大概的场景。
我的疑问点在于:我觉得和第一种漏标是一样的,那为什么不能用写屏障?在把A的属性1指向D的时候把A修改成灰色。问题不还是解决了吗?看懵我了!!!
实际此处和第一种漏标有两种区别,只是视频中没有特别指出。
1.在m2(业务逻辑线程)把属性1指向D时,此时A是灰色的,第一种漏标中通过写屏障把A改为灰色的操作就没意义了。
2.m3(垃圾回收线程)继续运行时,即使A是灰色也不会重新全部标记,而是继续之前的操作继续标记属性2,然后就把A标记为黑。因为没用重新标记属性1所以D就被漏标了。(如果是第一种漏标通过写屏障改A为灰色时,m3会对所有属性重新标记)(是不是可以通过写屏障标识要对A的所有属性重新标记呢?)
而对应的解决方法就是cms第三阶段会STW的重新标记。