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指针恢复上一个灰链。
    另外,说灰链中的对象不意味着对象是灰色。

lua 垃圾回收标记函数 reallymarkobject

lua垃圾回收标记函数
  • vinsberg
  • vinsberg
  • 2015年11月21日 23:08
  • 264

lua的垃圾回收机制

垃圾回收的目的是要释放掉不再被使用变量所占用的内存。 Lua的垃圾收集机制使用了名为标志和清扫(Mark-and-Sweep)的方式。默认情况下,所有变量都标记为“可回收”,回收是从根节点_G出发,...
  • xufeng0991
  • xufeng0991
  • 2015年03月31日 10:53
  • 3163

Lua垃圾回收

Lua 通过特定算法的垃圾回收机制实现自动内存管理。由于自动内存管理机制的存在,作为程序开发人员: 不需要关心对象的内存分配问题。不再使用对象时,除了将引用它的变量设为 nil,不需要主动释放对...
  • cbbbc
  • cbbbc
  • 2016年03月24日 11:03
  • 566

lua垃圾回收机制

一、检测lua内存泄漏: 注:使用“collectgarbage("collect")”,局部变量v被回收,my_list没有被回收。 注:局部变量v占用的内存被回收。 ...
  • tianxiawuzhei
  • tianxiawuzhei
  • 2015年06月29日 11:32
  • 4964

简介三种垃圾回收机制:分代复制垃圾回收,标记垃圾回收,增量垃圾回收

一、分代复制垃圾回收 不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比...
  • Java_Grass
  • Java_Grass
  • 2017年03月17日 13:52
  • 1773

深入了解标记-清扫回收算法

摘自《the garbage collection handbook》     之前对标记-清扫回收算法的理解只是读完《深入理解Java虚拟机》里面的介绍,而对里面的很多细节不甚了解。看了《the ...
  • FoolishAndStupid
  • FoolishAndStupid
  • 2017年05月20日 11:06
  • 540

java垃圾回收算法之-标记压缩

转自:http://www.jianshu.com/p/698eb5e1ccb9 前言 内存碎片一直是非移动垃圾回收器(指在垃圾回收时不进行对象的移动)的一个问题,比如说在前面的标记-清除...
  • JJ_nan
  • JJ_nan
  • 2017年05月21日 21:25
  • 234

java垃圾回收算法之-CMS(并发标记清除)

CMS垃圾回收器
  • linsongbin1
  • linsongbin1
  • 2016年08月01日 09:38
  • 3673

增量式垃圾回收

简单的增量式垃圾回收通过这段时间对tinypy源码和编译原理这本书的研究,我终于敲开了增量式垃圾回收的“小门”;如果读者没有接触过基本的标记-清扫垃圾回收,最好先对其进行一定的了解。一、数据结构列表:...
  • u011320646
  • u011320646
  • 2015年12月27日 23:24
  • 1234

node学习笔记--- v8的垃圾回收机制

以下内容基本摘自《深入浅出Node.js》         v8作为JavaScript引擎是非常优异的,在浏览器的应用场景中是绰绰有余的,但是其固有的内存限制(64位系统下约1.4GB,32位系统...
  • CraigChencc
  • CraigChencc
  • 2016年08月06日 17:00
  • 413
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:lua 垃圾回收标记函数 reallymarkobject
举报原因:
原因补充:

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