C ++垃圾收集编译器

时间:2013-05-06 04:48:17

标签: c++ c++11 garbage-collection

有没有人知道一个支持垃圾收集的c ++的好编译器。我知道他们正在考虑使用c ++ 11,但没有实现它。

2 个答案:

答案 0 :(得分:6)

最常听到的方法之一是使用Hans Boehm的GC,它可以插入C ++。当然,另一种方法是使用智能指针来跟踪对象的使用。

对于那些赞成“谁需要这个”评论的人来说,答案是它可能更贵:

  • 想象一下你fork()你的程序,现在开始调整保持常量的对象中的refcounters。这将导致性能开销,因为这意味着操作系统无法在两个进程之间共享内存,即它会破坏写时复制。在某些情况下,这可能意味着操作系统必须仅在内存中交换以复制和调整参考计数器。
  • 另一个例子是建议的boost::shared_ptr。这些中的每一个都具有额外的分配作为开销以便存储参考计数器,弱参考计数器和删除器。这也不是免费的。此外,其实例的大小是指针的两倍。
  • 然后,如果您使用正常size_t进行refcounter和内置递增/递减,则代码不是多线程安全的。但是,如果使用原子整数,则递增和递减需要花费更多时间来刷新缓存,因为它不允许重新排序。请记住,每次复制这样的指针时,都必须增加引用计数器。每次销毁一个实例时,都必须再次递减计数器。维护引用计数可能会累积到更高的开销,使用标记和扫描GC来不时计算引用。
  • 最后,refcounted指针需要程序员积极考虑循环的可能性。 GC可以自动检测和中断循环。

如果你牢记上述内容,那么GC就是另一种选择。它确实有缺点,比如非确定性清理,但是Java和C#表明你可以忍受这个,并且没有任何东西可以阻止你在你真正需要的地方自己编程。

答案 1 :(得分:1)

通常,您可以使用RAII和智能指针(例如C ++ 11中的shared_ptrunique_ptr)来解决问题。

但是,如果你需要垃圾收集,请查看Boehm的垃圾收集器。您可以按以下方式重载operator new

enum GCPlacement {
    NoGC,
    GC,
};

void* operator new(size_t size, GCPlacement gcp) {
    void* toReturn;

    if (gcp == GC) toReturn = GC_MALLOC(size);
    else toReturn = GC_MALLOC_UNCOLLECTABLE(size);

    if (!toReturn) throw std::bad_alloc();
    else return toReturn;
}

void operator delete(void* p, GCPlacement) {
    GC_FREE(p);
}

现在,您可以按如下方式分配垃圾回收内存:

Object* o = new (GC) Object();

如果需要,您还可以从boehmgc提供的gc类派生某些类,以指示应始终使用垃圾收集分配这些类。

C ++ / CLI是另一种解决方案,但请注意,它在技术上不是C ++(它是C ++部分实现的扩展)并且它将您与Microsoft / .NET平台联系起来 - 实质上,它只是C#与一个C ++语法。