1 如何判定对象是否需要GC?
在GC周期,从根节点进行遍历检查,对GC对象进行分类标记来达到增量回收的目的。
1.1 颜色标记
使用3种颜色:白、灰、黑。
- 白表示该对象没有被标记,对象创建时的默认标记。
- 灰表示该对象已被标记,但它的引用对象可能还没有被标记。
- 黑表示该对象及它的引用都已标记。
1.2 两种白
由于GC是增量式进行,所以在回收周期过程可能会新增对象。为了避免新增对象被误回收,所以需要使用另一种白进行标记,这种白也会作为下一个回收周期的白。白1和白2就这样不断交替切换。
static l_mem atomic (lua_State *L) {
...
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
....
}
通过上面源码,两种白的切换时机在回收周期的清除阶段开始前进行。
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
通过上面源码可以知道判断对象是否可回收是通过isdead判断两种白色计算得出。
- 有被引用的为黑色,没被引用的保持创建时的白色,即白色是回收对象的颜色。