随笔 - 119  文章 - 290  trackbacks - 0

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

常用链接

留言簿(12)

随笔分类

我的博客

搜索

  •  

积分与排名

  • 积分 - 302262
  • 排名 - 84

最新评论

阅读排行榜

昨天已经通过gc_enterstack_push的实现,了解到用一个近似调用堆栈的东西,保存每一级调用中分配的自由内存的id。
今天看看gc_leave。gc_leave有一个可变参数列表,这些参数的用途是,将本函数分配的自由内存的声明周期再保留更长一点的时间。
看看实现就知道了:

 1void
 2gc_leave(void *p,)
 3{
 4    void **head;
 5    if (E.stack.current >= E.stack.bottom) {
 6        E.stack.top = E.stack.current;
 7        E.stack.current -= E.stack.data[E.stack.current].number;
 8    }

 9    else {
10        int parent,child;
11        --E.stack.bottom;
12        parent=E.stack.data[E.stack.bottom-1].stack;
13        child=E.stack.data[E.stack.bottom].stack;
14        node_add(parent, child | UNSET_MASK);
15        node_free(child);
16        E.stack.current=E.stack.bottom-1;
17        E.stack.top = E.stack.current + 1;
18    }

19
20    head=&p;
21
22    while (*head) {
23        stack_push(map_id(*head));
24        ++head;
25    }

26}

我们知道,调用gc_leave,也就意味着要离开当前的函数回到父函数上了,那么堆栈也要退回到父函数调用gc_enter后的情形。
首先看if部分,因为在 E.stack.current的位置上保存的是父函数中分配的自由内存的数量,所以第6行让top指向这里,第7行用current对这个数量做一个减法,就变成了父函数堆栈的情形了。

不过9行else部分比较令人困惑。仅仅在第一次调用gc_enter之前,current会小于bottom,此时current=0,bottom=1。那么接下来的第11行执行后bottom=0,第12行看起来就会访问索引为-1处的数据。我还没有跑过这个库,也没有在源码中搜索出 E.stack.bottom比较特殊的赋值操作,所以不太确定到底是怎么回事。所以,这个先暂时放下,等以后看到其他内容,或者跑一下这个库的时候,再搞清楚这段代码的意义。

最后是一个while循环,处理可变参数列表,这些参数是需要延长生命的自由内存指针。怎么做呢?因为现在已经回到了父函数的gc堆栈上,所以就把这些需要延长生命的自由内存压入父函数的gc堆栈即可,见23行。
不过这也意味着,他们的生命最少只延长到父函数也退出而已。

OK,看完了分配出来的内存的两种管理方式,明天终于可以看看如何进行内存回收了。
posted on 2008-09-18 20:00 LOGOS 阅读(1917) 评论(2)  编辑 收藏 引用

FeedBack:
# re: 垃圾收集的那点事(H)[未登录] 2008-09-20 12:45 好东西
特来支持一下,继续努力。  回复  更多评论
  
# re: 垃圾收集的那点事(H) 2013-12-30 17:11 7Qing_
非常感谢  回复  更多评论
  

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