在前面,谈到了关于GC的一些东西。网上关于GC的东西比较多,现在想想简单GC实现的问题。引用计数法是一个比较简单的想法。
引用计数,主要摘要是:
是唯一一种没有使用根集的垃圾回收算法,该算法使用引用计数器来区分存活对象和不再使用的对象。一般来说,堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器每次加1。当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就满足了垃圾收集的条件。
基于引用计数器的垃圾收集器运行较快,不会长时间中断程序执行,适宜必须实时运行的程序。但引用计数器增加了程序执行的开销,因为每次对象赋给新的变量,计数器加1,而每次现有对象出了作用域,计数器减1。
方法上,有两个重点:
1.在“幕后”操作地址分配、提供指针操作;
2.管理一个或多个列表,以维护在程序运行时分配的对象内存。
在实现上,有三个重点:
1.提供“幕后”操作的封装;
2.所维护的对象分配列表的信息;
3.便于进行查找的迭代器。
先看看方法,简单的讲就是:
通过对每个作用域的每种对象建立一个列表,以维护动态分配的每种对象的信息。该信息包含了该对象的地址,以及该地址被多少指针所引用(引用计数)。当一个新对象被成功分配了内存以后,同时就会在该列表中注册,并设引用计数为1;每当有其它指针指向该对象时,列表中更新该对象地址的引用计数加1.一个简单的策略是,进行垃圾回收的时间设在当对象操出作用范围。需要调用析构函数时,该对象地址引用计数减1;如果对象地址的引用计数减为0,则表示可以进行回收了。
在实现上:
C++中,通过重载操作符,以封装关于对象内存的分配,对象指针的操作。达到的效果是在语法上基本上是完全按C++语法编写程序。将需要保存在“垃圾列表”中的信息封装成一个类,以对象实例形式放于list中,便于管理。提供一个迭代器——当然,这不是必须的,以方便遍历维护的列表。