为什么C ++没有可选的透明垃圾收集器

时间:2010-12-29 21:26:49

标签: c++ garbage-collection

有一个相关的问题,但这个问题略有不同,我对相关问题的任何答案都不满意:)

我将通过断言不可能为C ++提供可选的透明垃圾收集器并希望有人证明我错了,从而对此问题表示否定。是的,Stroustrup尝试了这一点并且一再失败,不是因为技术问题,而是因为一致性问题。性能不是问题。

C ++永远不会有这样一个收集器的原因是可选一个没有收集器运行的程序必须手动实现所有必需的内存管理。添加收集器可能会带来一些性能优势,但不清楚它们是否值得(是的,收集器可以更快)。

您无法获得的是自动内存管理,这是需要收集器的主要原因。如果您选择进行正确的手动管理,您可以通过强制收集获得此功能(不必牺牲RAII或其他内容)。具有可选手动内存管理功能的强制收集器是可行的。

不幸的是,获得强制收集器的唯一方法是创建与不使用收集器的早期版本的C ++不兼容:换句话说,如果我们想要自动透明内存管理,我们必须定义一种新语言。

所以我的论点是:C ++永远不会有垃圾收集,因为它被锁定在需要向上兼容的历史开发中:强制收集和可选的手动内存管理是可行的,但透明的可选垃圾收集不是。

通过展示一个可选的透明垃圾收集模型证明我错了!

编辑:

Oooo ..我想我有答案。有人可以引用标准,它需要程序删除堆分配的对象吗?

因为:该子句(如果存在)是阻止可选透明垃圾收集的唯一事物。甚至可能有足够的时间从C ++ 1x中删除该子句。

如果没有这样的子句,程序可能会泄漏内存而不会出现未定义的行为:内存不足时的行为与通常情况相同。因此,对垃圾收集器进行处理将对指定的语义无效:它们是否定义良好,与是否使用收集器无关。

6 个答案:

答案 0 :(得分:11)

  

通过展示一个可选的透明垃圾收集模型证明我错了!

请参阅:C++/CLI

将垃圾收集器与现有C ++代码放在一起的困难在于C ++通常依赖于确定性对象破坏以使事情发生;正如在RAII中所做的那样。当然,垃圾收集器能够使大多数类型的内存RAII透明,但是大量与RAII相关的概念与内存无关。例如,套接字,流和锁都适用于某种形式的RAII管理,如果不保留确定性破坏,这些都不会很好。

因此,它可能不会是“透明的” - 它必须是像C ++ / CLI这样的东西,你必须说“我希望这是垃圾收集” - 但它无论如何都是合理的可能的。

答案 1 :(得分:9)

这可能更适合作为评论而不是答案,并且可能会引发许多暗示。就这样吧。

每当有人问诸如“为什么C ++不能使用GC?”之类的问题时。我觉得自己“因为不希望你的垃圾收集。我想控制对象何时生存。我想控制对象何时死亡。我希望破坏和解除分配是确定性的,而不是基于在一些hokus pokus black magic上。我不需要GC来编写更好的程序。因此,GC不会对我做任何事情,但会妨碍我。“

但即便如此,请考虑这一点。 C#和其他.NET语言都内置了GC。这些语言的编译器和CLR主要是用C ++编写的。这包括内存管理工具,除了一些用汇编语言编写的性能关键部分。

所以你可能会说C#可以做的任何事情,C ++可以做,因为C ++生成C#。

继续,向下倾斜......

答案 2 :(得分:1)

我认为你采取了错误的做法。 GC没有理由透明 - 为什么没有std::gc_pointer<T>

您需要考虑GC的真正目的。这不是为了解决内存管理问题,因为现有的智能指针(在C ++ 0x中)解决了这个问题就好了 - 它为手动内存管理提供了不同的性能特性,非常适合临时分配。为什么不只是有一个std :: gc_new?我们已经有了一个std :: make_shared。

并且,在C ++ 0x中,已经实现了是否自动删除了未删除的对象。

答案 3 :(得分:1)

“为什么我的兰博基尼没有雪犁刀座?”因为它不是为除雪而设计的;)

C ++的设计并不像C#,具有不同的用途。使用正确的工具来完成正确的工作,生活更加轻松。

答案 4 :(得分:1)

真正的问题不在于确保确定性地发生对象破坏(可能没有太多麻烦:当一个对象超出范围时(或者在堆分配对象的情况下调用delete) ),它的析构函数可以调用,而实际的内存回收可以留到以后的垃圾收集) - 而是如何识别要收集的

为此,GC需要能够遍历对象图。 在“正确”的GC语言中,这很简单,因为每个对象都用某种类型的指针标记,允许GC知道它正在访问的对象的结构。

在C ++中,通常没有这样的东西。 GC无法知道它所看到的单词是否是指针,同样重要的是, next 单词是否是同一结构/数组的一部分,或者是否它是未分配的。

当然,该标准并没有禁止实现添加这样的类型信息,但这会在运行时性能和内存使用方面带来成本,这与C ++的“你只为你使用的东西付费”的理念是不相容的。 / p>

存在的GC采用的另一种选择是实现一个保守的GC,它可能不会回收所有内存,因为它必须猜测一个字是否是一个指针,当有疑问时,它必须是悲观的。

答案 5 :(得分:0)

我可以通过为C ++提供可选的透明垃圾收集器示例来证明您的错误吗?

对于这样的问题,还需要阅读a good discussion on the Boehm site