随笔 - 119  文章 - 290  trackbacks - 0

博客搬家了哦,请移步
叫我abc

常用链接

留言簿(12)

随笔分类

我的博客

搜索

  •  

积分与排名

  • 积分 - 301920
  • 排名 - 84

最新评论

阅读排行榜

继上一篇,现在可以来看看gc_malloc的源码了,初窥究竟。
 1void*
 2gc_malloc(size_t sz,void *parent,void (*finalizer)(void *))
 3{
 4    void *ret=my_malloc(sz);
 5    int id=map_id(ret);
 6    E.pool[id].u.n.finalizer=finalizer;
 7    if (parent) {
 8        gc_link(parent,0,ret);
 9    }

10    else {
11        stack_push(id);
12    }

13    return ret;
14}

首先,第4行分配了指定大小的内存。
然后是第5行map_id(ret),这是什么呢?先不深究其实现,我简单的说说他所做的工作:
因为这是一个gc库,所以本质工作就是管理内存,因此将分配出来的新内存记录到一个容器中以便于以后的管理。yfgc管理采用的容器是一个数组。分配新内存后,在数组容器中找到一个空闲的位置,将内存指针记录到该位置上。
不过光做这个还是不够的,以后要是再遇上这块内存,怎么知道它被记录在数组容器的哪个位置上呢?虽然遍历查找也可以,不过我想应该没人会那么做吧。源码采用了hash_map,将这块内存的指针map到数组的索引上。
综上,map_id(ret)大体这么做了
pool[id].mem = ret;
map[ ret ] 
= id;
不过由于这个gc库是用C写的,没有STL,里面的代码就不可能那么简单啦。

总而言之,id就是内存在容器中的索引啦。从第6行可以看出,E.pool就是这个管理容器了。这句用来设置内存的析构回调函数。

E.pool是一个node结构数组,现在来看看node的定义,简单起见,我暂时去掉了不相关的东西:
1struct node {
2    union {
3        struct {
4            void * mem;
5            struct link *children;
6            void (*finalizer)(void *);
7        }
 n;
8    }
 u;
9}
;
mem和finalizer很眼熟对吧,因为刚刚才看过。children可以先不管,不过从名称看来,是管理父子关系,更准确的说是依赖关系的东东了。

OK,现在来看看7、8、9行,出现了gc_link,我记得这是一个public接口,用来管理两块内存之间的依赖关系的。现在,因为传入了parent实参,要在新分配的内存和parent之间建立依赖关系,所以调用了gc_link。

我想else部分可以先不管,只要记住出现了stack_push即可。现在非常好奇,gc_link是如何建立这一依赖关系的,采用了何种数据结构,所以接下来就要去看看gc_link的实现了。
posted on 2008-09-11 19:53 LOGOS 阅读(1950) 评论(1)  编辑 收藏 引用

FeedBack:
# re: 垃圾收集的那点事(B) 2008-09-11 20:20 陈梓瀚(vczh)
我在博客上的vczh free script里面有一个垃圾收集器。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理