一 Lua主要GC机制¶
1. 1 弱引用表¶
- 表:可为对象设置元表__mode字段,k键v值
a = {} mt = {__mode = "k"} setmetable(a, mt)
- 记忆技术:用辅助表记忆所有得到的结果(存储闭包,但可能随时间延长,需要弱引用表随gc清理)
- 对比默认值,根据情况判断优劣
- 可以引用非弱引用(活跃)对象作为键,不会回收
- 瞬表:弱引用键表中的值又引用对应的键。
- 对于瞬表来说,只有键的可访问性控制着对应值的可访问性。如果没有其他值强应用指向该值,弱引用瞬表仍然会被垃圾回收
1.2 析构器¶
元表__gc
,个人理解为析构函数- 析构顺序:被标记为析构处理的顺序的逆序调用。即:后标先析构
- (临时)复苏:析构器被调用的参数正在被析构,那么该对象会在析构期间变成活跃的
- 如果存储到全局变量,就会变成永久复数
1.7 垃圾收集器¶
lua 5.0前的机制¶
lua5.0前的机制依然是标记-清除GC
由于复苏存在,两个阶段: 1. 发现不可达放到析构队列。析构器开始执行则标记为已析构 2. 下一次垃圾收集在发现不可达,则删除 保证释放:两次collectgarbage,第二次才会删除第一次调用中被析构的对象
完整的垃圾收集机制: * 标记:将根结点集合(可以直接访问的对象)标记为活跃,只包括C注册表(如主线程和全局环境)。 * 活跃对象程序可达,也标记为活跃 * 清理:处理析构器和弱引用表。 * 将需要析构、都没有被标记为活跃的对象。标记活跃放到单独的析构列表中。 * 遍历弱引用表并从中移除键或值未被标记的元素 * 清除:遍历所有(所有对象在链表中),如果对象没有被标记为活跃,则回收。否则,Lua语言清理标记,开始下一个清理周期 * 析构:调用析构器
Lua5.1 增量式垃圾收集器¶
与解释器交替进行。解释器分配一段,收集器执行一小步 * 可达性有可能改变。因此引入发现和纠正改动的内存屏障
Lua 5.2 紧急垃圾收集¶
- 内存分配失败,强制进行一次完整垃圾收集,再分配。但不饿能运行析构器
1.8 控制垃圾收集步长¶
- pause : 等待内存使用多少时开始新的收集。200%指的内存使用翻番。
- sepmul:分配多少1kb就进行多少垃圾收集工作 *: 巨大的值如10000000%会表现成一个非增量垃圾收集。默认200%,100%很慢