65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (11投票s)

2004年7月31日

3分钟阅读

viewsIcon

130784

downloadIcon

892

C++ 垃圾回收库。

引言

LibGC 是一个非常小的库(大约 500 行代码),它为 C++ 提供了垃圾回收功能。它是在 MSVC++ 6.0 下开发、测试和使用的。

C++ 环境中内存管理的常见解决方案(除了使用垃圾回收器,例如 Hans - Boehm 垃圾回收器)是引用计数。 但是引用计数存在一些根本问题

  1. 循环引用
  2. 执行速度慢
  3. 编程困难

问题#1 是因为有一个计数器,用于计算有多少其他对象指向某个对象; 只有当对象的计数器达到 0 时才能释放该对象。不幸的是,当一个对象 A 指向另一个对象 B,而对象 B 指回 A 时,这两个对象将永远不会被释放,因为它们之间存在循环。

问题#2 是由于引用计数的工作方式造成的。 在每次赋值中,托管指针类都必须执行以下步骤

  1. 锁定资源(如果解决方案是多线程的)
  2. 将当前指针与新指针进行比较; 如果没有变化,则不执行任何操作
  3. 将当前指针值存储在临时变量中
  4. 将参数指针的值复制到指针成员
  5. 增加新对象的引用计数
  6. 减少上一个对象的引用计数
  7. 如果引用计数达到 0,则删除上一个对象
  8. 解锁资源(如果解决方案是多线程的)

以上所有操作都发生在每次赋值中;它们非常昂贵,并且会使程序运行非常缓慢,尤其是在程序有数千个指针的情况下(例如,在堆栈上)。

问题#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日:初始版本

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.