AGM::LibGC: C++ 垃圾回收库






4.67/5 (11投票s)
2004年7月31日
3分钟阅读

130784

892
C++ 垃圾回收库。
引言
LibGC 是一个非常小的库(大约 500 行代码),它为 C++ 提供了垃圾回收功能。它是在 MSVC++ 6.0 下开发、测试和使用的。
C++ 环境中内存管理的常见解决方案(除了使用垃圾回收器,例如 Hans - Boehm 垃圾回收器)是引用计数。 但是引用计数存在一些根本问题
- 循环引用
- 执行速度慢
- 编程困难
问题#1 是因为有一个计数器,用于计算有多少其他对象指向某个对象; 只有当对象的计数器达到 0 时才能释放该对象。不幸的是,当一个对象 A 指向另一个对象 B,而对象 B 指回 A 时,这两个对象将永远不会被释放,因为它们之间存在循环。
问题#2 是由于引用计数的工作方式造成的。 在每次赋值中,托管指针类都必须执行以下步骤
- 锁定资源(如果解决方案是多线程的)
- 将当前指针与新指针进行比较; 如果没有变化,则不执行任何操作
- 将当前指针值存储在临时变量中
- 将参数指针的值复制到指针成员
- 增加新对象的引用计数
- 减少上一个对象的引用计数
- 如果引用计数达到 0,则删除上一个对象
- 解锁资源(如果解决方案是多线程的)
以上所有操作都发生在每次赋值中;它们非常昂贵,并且会使程序运行非常缓慢,尤其是在程序有数千个指针的情况下(例如,在堆栈上)。
问题#3 是由于引用计数的工作方式造成的。 应特别注意手工制作析构函数,以避免多次删除同一个内存块,这是一项非常复杂的任务。 许多程序员倾向于围绕共享对象创建包装类,以避免此问题,但随后他们必须管理两个具有相同接口的类:包装类和内部类。
LibGC 提供的解决方案没有这些缺点。 在循环中引用的对象会被正常收集和删除,该库通常在执行垃圾回收时非常快,并且不需要包装类。
LibGC 使用保守的标记-清除停止-世界算法来收集垃圾数据。 程序员像往常一样编写 C++,使用指针等,但对象不需要删除。 对象删除的工作方式与往常一样。
LibGC 的许可证是 LGPL。
使用 LibGC 非常简单; 只需像往常一样编程
- 使用 operator new 分配对象
- 使用 宏 GC_NEW 分配需要终结的对象
- 从 Object 类 继承您的类,以便在使用
GC_NEW
的情况下自动进行终结 - 如果需要删除对象,请使用 operator delete 删除它们
- 在堆栈上声明对象
- 全局声明对象(在程序的数据段中)
- 通过调用 函数 doGC() 手动进行垃圾回收
删除正常工作:您可以随时删除对象,并且对象占用的内存不再被垃圾回收。
当应用程序退出时,所有对象都会被终结,并且内存会被释放。
Object 类位于 agm::gc
命名空间中。
示例
//use garbage collection #include "gc.hpp" using namespace agm::gc; //include some STL class for demonstrating the global use of operator 'new' #include <list> using namespace std; //a class that is not automatically finalized class Foo { public: }; //a class that is automatically finalized class Bar : public Object { public: }; //main int main() { //allocate a Foo object with macro GC_NEW //because it is not automatically finalized Foo *obj1 = GC_NEW(Foo)(); //allocate an STL list that is not automatically finalized; //nodes will be freed by the collector list<int> *obj2 = new list<int>; //allocate a Bar object with operator 'new' //that is automatically finalized //since it inherits from Object Bar *obj3 = new Bar; }</int></int>
一旦超过 GC_THRESHOLD 字节未被收集,该库将自动收集垃圾。
- 注意 1:该库是在 MSVC++ 6.0 下开发和测试的。 它也可能在其他编译器下运行。 如果您想测试它并告诉我,请随时这样做:您将被添加到贡献者列表中。
- 注意 2:必须启用异常。
- 注意 3:该解决方案不适用于多线程应用程序(尚未)。
有关更多信息,您可以访问我的小网站这里。
历史
- 2004年7月31日:初始版本
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。