我问这个问题,首先不是因为垃圾收集的优点。我问这个问题的主要原因是我知道Bjarne Stroustrup说过c++在某个时间点上会有一个垃圾收集器。

话虽如此,为什么还没有加入呢?c++已经有了一些垃圾收集器。这是那种“说起来容易做起来难”的事情吗?或者还有其他原因没有添加它(并且不会在c++ 11中添加)?

交叉链接:

c++的垃圾收集器

澄清一下,我理解c++最初创建时没有垃圾收集器的原因。我想知道为什么不能添加收集器。


当前回答

要回答关于c++的大多数“为什么”问题,请阅读c++的设计与进化

其他回答

所有的技术讨论都使这个概念过于复杂。

如果您将GC自动放入c++以获取所有内存,那么可以考虑使用类似web浏览器的东西。web浏览器必须加载完整的web文档并运行web脚本。web脚本变量可以存储在文档树中。在打开大量选项卡的浏览器中的大文档中,这意味着每次GC必须进行完整收集时,它还必须扫描所有文档元素。

On most computers this means that PAGE FAULTS will occur. So the main reason, to answer the question is that PAGE FAULTS will occur. You will know this as when your PC starts making lots of disk access. This is because the GC must touch lots of memory in order to prove invalid pointers. When you have a bona fide application using lots of memory, having to scan all objects every collection is havoc because of the PAGE FAULTS. A page fault is when virtual memory needs to get read back into RAM from disk.

因此,正确的解决方案是将应用程序分为需要GC的部分和不需要GC的部分。在上面的web浏览器示例中,如果文档树是用malloc分配的,但javascript是用GC运行的,那么每次GC启动时,它只扫描一小部分内存,并且文档树的内存中所有page OUT元素不需要被换回。

为了进一步理解这个问题,请查阅虚拟内存以及它是如何在计算机中实现的。这都是关于当没有那么多RAM时,程序可用2GB的事实。在32BIt系统的2GB RAM的现代计算机上,只要只有一个程序在运行,就不存在这样的问题。

作为另一个示例,考虑一个必须跟踪所有对象的完整集合。首先,您必须扫描所有通过根访问的对象。第二步扫描步骤1中可见的所有对象。然后扫描等待的析构函数。然后再次浏览所有页面,关闭所有不可见对象。这意味着许多页面可能会被多次换出和换回。

因此,我的回答是,由于触及所有内存而发生的PAGE FAULTS的数量导致对程序中所有对象进行完整的GC是不可行的,因此程序员必须将GC视为脚本和数据库工作的辅助,但使用手动内存管理进行正常工作。

另一个很重要的原因当然是全局变量。为了让收集器知道全局变量指针在GC中,它需要特定的关键字,因此现有的c++代码将无法工作。

什么类型?它应该针对嵌入式洗衣机控制器、手机、工作站或超级计算机进行优化吗? 它应该优先考虑gui响应还是服务器加载? 它应该使用大量内存还是大量CPU?

C/c++被用于太多不同的环境。 我怀疑像增强智能指针这样的东西对大多数用户来说就足够了

编辑:自动垃圾收集器并不是一个性能问题(你总是可以购买更多的服务器),而是一个可预测的性能问题。 不知道GC什么时候会起作用就像雇佣一个嗜睡症的飞行员,大多数时候他们是很棒的-但当你真的需要响应的时候!

简短的回答: 我们不知道如何高效地(在很少的时间和空间开销下)并且始终(在所有可能的情况下)正确地进行垃圾收集。

长一点的回答: 就像C一样,c++是一种系统语言;这意味着当您编写系统代码时,例如操作系统时,将使用它。换句话说,c++就像C一样,以尽可能好的性能作为主要目标。该语言标准不会增加任何可能阻碍性能目标的特性。

这暂停了这个问题:为什么垃圾收集会影响性能?主要原因是,当涉及到实现时,我们(计算机科学家)不知道如何在所有情况下以最小的开销进行垃圾收集。因此,c++编译器和运行时系统不可能一直有效地执行垃圾收集。另一方面,c++程序员应该了解他的设计/实现,他是决定如何最好地进行垃圾收集的最佳人选。

最后,如果控制(硬件、细节等)和性能(时间、空间、电源等)不是主要的限制,那么c++就不是合适的工具。其他语言可能会更好,并提供更多[隐藏的]运行时管理,以及必要的开销。

本来可以添加隐式垃圾收集,但它没有达到要求。可能不仅仅是因为实现的复杂性,还因为人们不能足够快地达成普遍共识。

引用Bjarne Stroustrup自己的话:

我本来希望是个收垃圾的 哪些可以选择启用 是c++ 0x的一部分,但是 我有足够多的技术问题 凑合着用一个详细的 如何规范这样的收集器 的其余部分集成 语言,如果提供的话。事实就是这样 基本上拥有c++ 0x的所有特性, 存在一个实验性的实现。

这里有关于这个话题的很好的讨论。

总体概述:

c++非常强大,几乎可以做任何事情。由于这个原因,它不会自动将许多可能影响性能的东西推给您。垃圾收集可以很容易地用智能指针(用引用计数包装指针的对象,当引用计数达到0时自动删除自己)实现。

c++在构建时考虑到了没有垃圾收集功能的竞争对手。与C和其他语言相比,效率是c++必须抵御批评的主要问题。

垃圾收集有两种类型…

显式垃圾收集:

c++ 0x通过shared_ptr创建的指针进行垃圾收集

如果你想要它,你可以使用它,如果你不想要它,你不会被迫使用它。

对于c++ 0x之前的版本,boost:shared_ptr是存在的,用途相同。

隐式垃圾收集:

但是它没有透明的垃圾收集。不过,它将是未来c++规范的一个焦点。

为什么Tr1没有隐式垃圾收集?

c++ 0x的tr1应该有很多东西,Bjarne Stroustrup在之前的采访中说tr1没有他想要的那么多。

c++背后的思想是,你不需要为你不使用的特性付出任何性能上的影响。因此,添加垃圾收集意味着让一些程序像C语言那样直接在硬件上运行,而另一些则在某种运行时虚拟机中运行。

没有什么可以阻止您使用绑定到某些第三方垃圾收集机制的某种形式的智能指针。我似乎记得微软在COM上做过类似的事情,但并不顺利。