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

  程序变量中任何指针链无法到达的堆分配记录都称为垃圾信息。而被垃圾信息填满的内存空间应该收集,以便重新分配新的记录,而这个过程就叫做垃圾信息回收,它是编译器的后端来执行的。对于以下一个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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值