在C++中创建垃圾回收器:
由于C++是一种功能丰富强大的语言,因此有许多不同的方法可以建立垃圾回收器。一个明显但受限制的方法就是基于建立一个垃圾回收器,想要使用垃圾回收的类可以从这个类继承。这样做可以使得一个类接一个类地实现垃圾回收。但遗憾的是,这种方案太有限而不能令人满意!
更好的解决方案是建立一个可以被任何动态分配的对象使用的垃圾回收器。为了提供这种解决方案,垃圾回收器必须满足以下要求:
- 与内建的、C++提供的手工方法共存;
- 不要破坏任何预先存在的代码。更重要的是,不应该对现有的代码造成任何影响;
- 透明的运行,从而利用垃圾回收的分配与不适用这个方案的运行方式相似;
- 类似于C++内建的方法,使用new来分配内存;
- 对所有的数据类型都有效,包括内建的类型,如int和doube类型;
- 易于使用;
总之,垃圾回收系统必须非常接近C++已经使用的机制和语法来动态分配内存,并且不能响应现有的代码。咋看上去,这好像是一个令人生畏的任务,但是事实并非如此。
理解这个问题
在建立垃圾回收器的时候,面临的关键问题是如何知道某一块内存不再使用。为了理解这个问题,考虑下面的序列:
int *p;
p = new int(99);
p = new int(100);
在此动态分配了两个int对象。第一个对象包含的值为99,指向这个指针存储在p中。然后,分配了一个值为100的整型数据,其地址也存储在p中,从而改写了第一个地址。在此改写了第一个地址。在此,p(或者其他对象)不再指向int(99)的那块内存,从而可以释放这个内存。问题是,垃圾回收器如何知道p或者其他的对象都不指向int(99)了呢? 对这个问题稍作变动:
int *p,*q;
p = new int(99);
q = p;
p = new int(100);
在此情况下,q指向了原先为p分配的内存。即使p指向了不同的内存块,原先指向的内存也不能被释放,因为q仍然在使用它。问题是:垃圾回收器如何知道这一事实呢?对这个问题的准确回答取决于垃圾回收所使用的算法。