上次示例了一个简单的,以“引用计数法”实现的GC工具。但是,从设计的框架上来看,在有循环引用存在的时候,这个GC工具会在垃圾收集的时候陷入死循环。
  网上有段话,大概是这样来诠释循环引用的:
  如果建立了一个类“Class人”,他有个属性 “手”。
 

private Class手 _手; 
  public Class手 手 { 
 get { return _手; } 
  }


  而在Class手,我希望能够访问“父”,就是人,例如手在收到烫伤后,立即通知“父”:人的子对象“大脑”一个消息“好痛啊”。这个时候,就需要在Class手中定义一个“人”属性,并在Class人初始化时将自己传入。
  _手 = new Class手();
  _手.人 = this; 事实上,这样的做法将造成了“循环引用”的问题。因为人引用了手,而手又引用了人,如果试图释放人,将先要释放手,但释放手的前提是要释放人,这就是“循环引用”。

  关于这个问题的解决,想必方法也有几种。其中之一就是“弱引用”如果人引用手(真引用),但手弱引用了人,这样释放人的时候,先释放手,而释放手将不再需要先释放人。
  这段时间暂没有找到比较正式的,关于弱引用解决方案更详细的描述文献。不过从网上的类似描述来看,我有了一点思路:即是说,如果要防止GC在工作时进入循环引用的陷阱,最直观的一种方案即是打破循环链;而打破循环链的一个方法,就是使用“弱引用”。

  针对上次的GC实现,可以发现循环来自于在对象生存期间维护的gcList链表,因为如果一旦有两个类对象实现了循环引用,则会在它们的生存空间中去查找各自类型的而又唯一的链表地址记录,而两个链表所保存的信息不可能反映地址逻辑上的从属关系,这样一来,两者就没有父 - 子之分,而造成循环。
  基于这一点看法和对此问题有限的认识,我觉得可以实现一个弱引用的类WeakRefGCPtr<T>,和原来的GCPtr<T>一起工作。以期在需要有弱引用的地方使用WeakRefGCPtr<T>的实例,从而截断循环链。

 回头写了点东西,测试了一下,能解决上面的问题,暂时没有发现bug,再检查一下,过两天把实现和思路帖上来。如果有好想法,或是发现我这种简单思路有问题的朋友,还请多提示一下。