lua 垃圾回收标记函数 reallymarkobject

原创 2015年11月19日 23:53:42

reallymarkobject 函数如下(省略旁路代码):

static void reallymarkobject (global_State *g, GCObject *o) {
  white2gray(o);
  switch (o->gch.tt) {
    case LUA_TSTRING: {
      return;
    }
    case LUA_TUSERDATA: {
      Table *mt = gco2u(o)->metatable;
      gray2black(o);  /* udata are never gray */
      if (mt) markobject(g, mt);
      markobject(g, gco2u(o)->env);
      return;
    }
    case LUA_TUPVAL: {
      UpVal *uv = gco2uv(o);
      markvalue(g, uv->v);
      if (uv->v == &uv->u.value)  /* closed? */
        gray2black(o);  /* open upvalues are never black */
      return;
    }
    case LUA_TFUNCTION: {
      gco2cl(o)->c.gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TTABLE: {
      gco2h(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TTHREAD: {
      gco2th(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
    case LUA_TPROTO: {
      gco2p(o)->gclist = g->gray;
      g->gray = o;
      break;
    }
  }
}

首先解释下三色标记法,GC中用三种颜色标记不同的对象:

(1) 黑色:本身强引用,并已处理对象中的子引用

(2) 灰色:本身强引用,还没处理对象中的子引用

(3) 白色:不可达对象

三色标记法中,黑色和白色不可能直接相连,任何被黑色对象引用的对象都意味着是可达的(即不能是白色),必须有灰色来过渡。

解释完三色标记法之后,我们具体来看标记函数。

标记函数实际上是一个大switch case结构。函数首先把所有白色对象都标记成灰色,然后对每个具体类型,做具体标记,下面按类型来分析。

  1. 字符串
    所有字符串对象,无论是长串还是短串,都没有引用其他对象。我们看到字符串类型标记成灰色后直接返回了。字符串是永远不会被标记成黑色?

  2. userdata
    我们看到userdata类型对象直接是标记成黑色,然后立即标记它的元表和环境表。在这里markobject实际还是调用的reallymarkobject函数,因此产生递归。

  3. 自由变量(upvalue)
    自由变量脱离创建它的作用域的时候(closed),此时自由变量指向本身,直接标记成黑色;否者自由变量实际上是引用栈上的值,这个时候相当于弱引用,依附于栈。

  4. 函数|表|线程|原型
    我们可以看到对象保存着当前标记之前的全局灰链,然后把自身赋予给灰链,并标记自己为黑色。把这些本身强引用,但还没处理对象中的子引用对象串联起来。在扩散标记阶段,处理标记灰链中对象的时候,处理完子饮用后,就可以通过对象的gclist指针恢复上一个灰链。
    另外,说灰链中的对象不意味着对象是灰色。

GC垃圾回收的三色标记算法

GC中用三种颜色标记不同的对象(1)黑色:本身强引用,并已处理对象中的子引用(2)灰色:本身强引用,还没处理对象中的子引用(3)白色:不可达对象 Mark扫描时根据状态进行标记...

标记清除法和增量回收算法

笔记摘录,希望可以给大家一些思路,真正需要的朋友们可以去读原书~~
  • njys1
  • njys1
  • 2016年12月17日 18:58
  • 349

02.2跟雨痕看go源码- 并发清理与三色标记

go gc三色标记与清理

jvm三色标记

2)标记过程 标记过程采用的算法为DFS三色标记算法。 这里大致介绍一下三色标记法:如果节点当中有3个颜色,白色,灰色和黑色,白色代表这个节点从来没有被处理过,灰色代表正在被处理,黑色代表已经被处...

Linux多线程——使用信号量同步线程

信号量、同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过是同步的对象不同而已。但是下面介绍的信号量的接口是用于线程的信号量,注意不要跟用于进程间通信的信号量混淆。相似地,线程同步...
  • ljianhui
  • ljianhui
  • 2013年09月01日 00:09
  • 42856

Java JVM 4:CMS 垃圾收集器 - 工作原理,浮动垃圾,三色标记法等

CMS 全称为 Concurrent Mark Sweep。它是现在非常主流的一款老年代的垃圾回收器,因为它能够实现和用户线程并行进行,而不需要像其他的垃圾收集器一样(如 Serial Old,Par...

lua 垃圾回收标记函数 reallymarkobject

lua垃圾回收标记函数

java垃圾回收算法之-标记清除

java垃圾回收算法之-引用计数器,这个算法其中一个优点便是,实时性,只要对象的引用计数器的值为0,则立刻回收。接下来介绍的标记清除算法,当对象的引用计数器的值为0时,不会立刻被回收的。概念介绍roo...

Java垃圾回收精粹——串行收集器、并行收集器以及并发标记清理收集器(CMS)

串行收集器(Serial Collector) 串行收集器是最简单的收集器,对于单处理器系统真是绝佳上选。当然,它也是所有收集器里面最不常用的。串行收集器使用一个单独的线程进行收集,不管是次要收集还...

java垃圾回收算法之-标记清除

前言 垃圾自动回收机制的出现使编程更加的简单,使得我们不需要再去考虑内存分配和释放的问题,而是更加的专注在我们产品功能的实现上。但是我们还是需要花时间去了解下垃圾收集机制是怎么工作的,以便后面能够更...
  • JJ_nan
  • JJ_nan
  • 2017年05月21日 21:11
  • 166
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:lua 垃圾回收标记函数 reallymarkobject
举报原因:
原因补充:

(最多只允许输入30个字)