Ruby的GC机制源码分析(4)

 

标记

正如说过的那样,ruby 的GC是标记和清除型。具体来说,标记就是设置FL_MARK 标志。搜索已用的VALUE ,设置FL_MARK ,全部检查过之后,再来看对象堆,释放那些没有设置FL_MARK 的对象。

rb_gc_mark()

rb_gc_mark() 是一个递归标记对象的函数。

rb_gc_mark()

 

 

首先,RANY() 定义如下。没什么特别的。

RANY()

 295  #define RANY(o) ((RVALUE*)(o))

(gc.c)

首先,检查那些不是指针的东西和已经释放的对象,以及对已标记对象的递归检查。

obj->as.basic.flags |= FL_MARK;

这样obj (也就是函数的参数ptr )就被标记了。之后,顺着从obj 出来的引用进行标记。rb_gc_mark_children() 就是这样。

其它的,从CHECK_STACK() 开始,主要是为了写了些各种各样防止栈溢出的代码。 rb_gc_mark() 使用递归调用对对象进行标记,如果出现大的对象簇,机器栈的长度可能就会不足。在栈要溢出的时候,停止递归,将对象都放到全局列表中,再重新开始标记。因为这部分代码不是主线,省略过去。

rb_gc_mark_children()

下面是rb_gc_mark_children() ,它只是将内部类型罗列出来,然后标记,冗长无趣。这里省略了一些纯粹是枚举的部分。

rb_gc_mark_children()

 

 

rb_gc_mark() 是递归的调用,确认这点就可以了。省略的部分分别是NODET_xxxx 的枚举。 NODE 的事会在第二部分介绍。

T_DATA (用于扩展程序库的结构体)标记的部分需要确认一下。这段代码是从第二个switch 语句中提取出来的。

rb_gc_mark_children() -T_DATA

 789        case T_DATA:
790 if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj));
791 break;

(gc.c)

这里用的不是rb_gc_mark() ,也不是与之类似的函数,而是来自用户的函数dmark 。其中当然应该用到rb_gc_mark() ,不过,也可能不用。比如,一个极端的情况,用户定义的对象中不包含VALUE 就无需标记了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值