首先需要搞清楚什么是RootSet;
- 所有对象全部是白色
- RootSet直接关联的放入灰色标记表;
- 灰色标记表(如[a, b])中的对象直接管理的白色标记表中的对象也放入灰色标记表,同时原灰色标记表中的([a,b])放入黑色标记表;
- 重复步骤3,直至灰色标记表中没有任何对象;
- 释放白色标记表中的对象;(此时,存在在白色标记表中的对象可以认定没有任何可用对象对其引用)
强三色不变式/弱三色不变式?
强三色不变式: 禁止黑色对象引用白色对象
弱三色不变式:允许黑色对象引用白色对象但是有条件,该条件为:白色对象上游存在灰色对象引用白色对象;
为什么?
因为上述三色标记法中如果没有引入STW,这样的情况可能会造成,在运行时出现问题;
比如,开始灰色对象H引用了白色对象Q,但运行期间,黑色对象B引入了白色对象W(注1),同时H丢失了对Q的引用(注2),造成的结果是Q被回收,而,Q不应该被回收,因为此时B引用了Q,但B已经是黑色对象,不在往下标记Q为灰色造成的;
为了解决这种问题,引入机制----屏障
插入屏障 :针对注1(当一个对象被引用时)
A对象如果要引用B对象,那么B对象必须放入灰色标记表(把B变为灰色);
这里面会有一个问题,就是效率的问题,所以栈上是不使用插入屏障的,那怎么保证不出问题???(这块是个大活,继续深入);在白色对象回收之前,会加入STW重新扫描一次栈空间;
删除屏障:针对注2 (当一个对象被删除引用)
如果被删除对象是灰色或白色,把该对象标记为灰色。
混合写屏障 + 三色标记法
开始时,栈上的对象全部标记为黑色
在栈上新创建的对象也标记为黑色
删除对象标记为灰色(不管是栈上还是堆)
被添加的对象标记为灰色;