Lua GC 控制 gcstepmul 和 gcpause

Lua gc 是分步进行的,什么时候开始做呢??
通过GCthreshold控制GC开始时机,GCthreshold就是触发GC的边界值。当一轮GC完整的完成后,GCthreshold 被设置成当前estimate的 gcpause / 100倍。estimate是剔除了userdata后的内存。
带_gc元方法的userdata在第一次被处理时只调用_gc元方法,第二次才是真正回收。在分配新内存时,通过luaC_checkGC检测 总内存是否超过GCthreshold,超过就触发一步GC。

那每步处理多少?
处理多少受gcstepmul影响

void luaC_step (lua_State *L) {
  global_State *g = G(L);
  //计算这一步要处理多少单位   0 的话就全部处理
  l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
  if (lim == 0)
    lim = (MAX_LUMEM-1)/2;  /* no limit */
  // 计算负债多少  预计是g->GCthreshold; 开始处理   但是现在已经 g->totalbytes 了
  g->gcdept += g->totalbytes - g->GCthreshold;
  do {
    //计算本次还剩多少要处理的
    lim -= singlestep(L);
    if (g->gcstate == GCSpause)
      break;
  } while (lim > 0);

  if (g->gcstate != GCSpause) {
    //处理完这次的量了
    if (g->gcdept < GCSTEPSIZE)
        // 欠债不太多了 那就扩大边界值
      g->GCthreshold = g->totalbytes + GCSTEPSIZE;  /* - lim/g->gcstepmul;*/
    else {
     // 欠债太多了 怎么办  那就不停下继续GC吧
      g->gcdept -= GCSTEPSIZE;
      g->GCthreshold = g->totalbytes;
    }
  }
  else {
    lua_assert(g->totalbytes >= g->estimate);
    //做了一次完整GC 重新设置边界值 为当前内存(扣除userdata)  *  gcpause /100  
    setthreshold(g);
  }
}


单步GC处理后将界限值调高了GCSTEPSIZE,也就是涨GCSTEPSIZE内存才发生GC。而每步GC处理的限制 (GCSTEPSIZE/100) * g->gcstepmul。
由此可见   处理  / 涨内存 = ((GCSTEPSIZE/100) * g->gcstepmul ) / GCSTEPSIZE = g->gcstepmul / 100  所以说gcstepmul就是相对于回收速率/分配速率的一个比值。
当gcstepmul <= 100 时 ,每步处理速率 <= 分配速率 ,可能导致无法完成一个完整的GC。gcstepmul越大,代表每步处理的对象越多,同时也会增加处理时间。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值