浅谈虎书中Java垃圾回收器(复制收集 )的实现

来源:互联网 发布:mysql 建库 utf8 编辑:程序博客网 时间:2024/05/17 05:10

  程序变量中任何指针链无法到达的堆分配记录都称为垃圾信息。而被垃圾信息填满的内存空间应该收集,以便重新分配新的记录,而这个过程就叫做垃圾信息回收,它是编译器的后端来执行的。对于以下一个Java模型可以转换为c代码:

 

//java code                                                                                                                                                         class  A{                                                                                                                                                                B x;                                                                                                                                                                              int y ;                                                                                                                                    C z;                                                                               int fuc(int a,B b,D d){                                                 E e;                                                                                                                                                                      int m;                                                                                                                                                                  F f;                                                                                                                                                                             }                                                                                                                                                                           }                                <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">                                                                                                                                         </span>

// c   code                                                                                                                                                                  Struct A{  Struct A_vatable;      //class A的虚函数表   Struct  B *x;            int y;          Struct C *z;        };       Struct A_vatable{     int  (*fuc)();  //通过它来调用A_fuc()函数       };                int A_fuc(A this,int a ,B b,D d){             //基本和fuc是一样的,A this主要是要用A的某些属性或者方法}                                          

                                                             }

在做复制收集的时候,以记录作为节点,指针作为边,程序变量作为根,堆中的可到达部分可以用一张直观的图来表示。垃圾回收时遍历这张图(在堆中称为from-space),然后在堆得一个新区域中(to-space)建立一个同构复制。to-space的复制时压缩的,它连续而没有分段的。

现在我们假设在Java  code的int fuc()中E e时发现from-space不够,需要进行垃圾回收。那么我们如何进行上述所说的遍历呢,这里我们要引入一个函数gc栈的数据结构。对于函数f()来说

T f (D this, int arg1, A arg2, B arg3){  A local1;  int local2;  C local3;  ... // statements}

它的gc栈应该是

struct f_gc_frame{  void *prev;                     // 指向调用f()的函数的gc栈  char *arguments_gc_map;         // 表示f()形参的引用变量个数,这里应该是"1011",D this是引用变量,所以是'1',int  arg1是整形所以是'0'  int *arguments_base_address;    // f()函数的第一个形参的地址(即D this),这样就可以通过它和char *arguments_gc_map取到所有的形参  char *locals_gc_map;            // f()函数局部变量的引用表示,这里应该是"101"  struct A *local1;               // 把f()所有的局部变量放进来  int local2;  struct C *local3;};

这样相应的f()函数中加入其gc栈要变化为

T f (D this, int arg1, A arg2, B arg3){  struct f_gc_frame frame;     // push this frame onto the GC stack by setting up "prev"  frame.prev = prev;  prev = &frame;   frame.arguments_gc_map = "1011";  frame.arguments_base_address = &this;  frame.locals_gc_map = "101";  // initialize locals of this method   ... // statements should be rewritten apporpriately

}
现在先通过遍历当前prev的所有引用型变量,然后在遍历prev.prev的所有引用型变量就把所有的根遍历了。这样就可以把他们从from-space全部都copy到to-space中。然后在在to-space中遍历所有对象中的引用,看是否拷贝到to-space即可。








0 0