跳转至

一 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%很慢