Lua的GC
主要的数据结构
- gobal_State 的成员变量
- GCObject **rootgc:存放待 GC 对象的链表,所有对象创建之后都会放入该链表中
- GCObject *gray:存放标记为灰色的 GC 对象的链表
- struct lua_State:*mainthread:主线程
- lu_byte currentwhite:存放当前GC的白色
流程
-
GC 对象的创建
- 将对象挂载到扫描过程会遍历的链表( rootgc )上
- 将对象的颜色设置为白色,意指本次GC还未扫描到的对象
-
初始化阶段(一次完成)
- 将 mainthread、G 表、registry 表的对象进行标记为灰色
- 这阶段的标记只是对对象单纯的标记,并没有进行递归的标记,为的是希望这个阶段尽快完成
-
扫描标记阶段(多次完成)
- 递归的扫描 gray 链表的对象,将它们及其引用的对象标记为黑色
-
回收阶段(多次完成)
- 遍历 rootgc 链表,回收标记为本次回收的白色的对象
-
结束阶段(多次完成)
- 回收自带 GC 元方法的 udata 对象
几个注意的点
- 关于 GC 的两种白色及为什么会有两种白色
- 假如一个对象在 GC 过程的标记阶段之后创建,它应该是白色的,这样在回收阶段,这个对象就会在没有被扫描标记的情况下被认为是没有被引用的对象而删除
- 关于局部 GC 对象
- 局部对象就存在于 mainthread 中,查看代码可以知道,在扫描标记阶段的时候,会对 mainthread(lua thread对象) 进行递归的标记,而对 thread 对象进行标记就是递归遍历其局部变量进行标记的
- 这里只对 GC 过程进行了简单的概括,各种 GC 对象的 GC 操作,barrier 操作等都没涉及,具体可以查看《Lua 设计与实现》第七章的内容