我唯一接触过垃圾回收机制是在几台廉价的80年代家用电脑上,它会导致系统每隔一段时间卡顿几秒钟。我相信它现在已经得到改进,但你可以想象,那并没有给我留下很高的评价。
对于有经验的C++开发者,垃圾回收机制可以提供哪些优势呢?
他们真的很可怜。
C++有RAII,而且我总是抱怨在垃圾收集语言中找不到RAII(或被削弱的RAII)。
另一种工具。
Matt J 在他的文章中( Garbage Collection in C++ -- why?)写得很对:我们不需要 C++ 的特性,因为它们中的大部分都可以用 C 代码实现,我们也不需要 C 的特性,因为它们中的大部分都可以使用汇编代码实现,等等。C++必须进化。
作为一个开发人员:我不关心GC。我尝试过RAII和GC,并发现RAII要好得多。就像Greg Rogers在他的文章中 (Garbage Collection in C++ -- why?)所说的那样,在C ++中内存泄漏并不是很可怕(至少在真正使用C++时很少出现),不能因为RAII来取代GC而不顾及内存选择。GC具有非确定性的释放/终止,只是一种编写代码的方式,不关心特定内存选择。
这句话很重要:编写“只是不关心”的代码很重要。就像在C++ RAII中我们不需要关心资源释放,因为RAII为我们完成了它,或者对于对象初始化,因为构造函数为我们完成了它一样,有时仅仅编写代码而不必担心哪个内存的所有者、为此或那个代码片段需要什么样的指针(共享、弱等)是很重要的。C++似乎需要GC。(即使我个人没有看到它)
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory>
using namespace std;
volatile sig_atomic_t got_sigint = 0;
class A {
public:
A() { printf("ctor\n"); };
~A() { printf("dtor\n"); };
};
void catch_sigint (int sig)
{
got_sigint = 1;
}
/* Emulate expensive computation */
void do_something()
{
sleep(3);
}
void handle_sigint()
{
printf("Caught SIGINT\n");
exit(EXIT_FAILURE);
}
int main (void)
{
A a;
auto_ptr<A> aa(new A);
signal(SIGINT, catch_sigint);
while (1) {
if (got_sigint == 0) {
do_something();
} else {
handle_sigint();
return -1;
}
}
}
但是垃圾回收可能会提供性能优势,特别是如果有很多短暂的对象被堆分配。垃圾回收还可能为新创建的对象提供更好的引用局部性(与堆栈上的对象相当)。
支持C++中GC的动机似乎是lambda编程、匿名函数等。事实证明,lambda库受益于能够分配内存而不必担心清理的能力。对普通开发人员的好处是更简单、更可靠和更快速地编译lambda库。
GC还有助于模拟无限内存;您需要删除POD的唯一原因是需要回收内存。如果您拥有GC或无限内存,则不再需要删除POD。
不需要追踪你那些经验不足的同事代码中的资源泄漏问题。
很多人错误地认为,因为C++语言本身没有内建垃圾回收机制,就不能在C++中使用垃圾回收。这是不正确的。我知道有精英级别的C++程序员会在他们的工作中使用Boehm垃圾回收器。
在某些情况下,GC的一个属性可能非常重要。在大多数平台上,指针的赋值自然是原子性的,而创建线程安全的引用计数(“智能”)指针则相当困难,并且会引入显着的同步开销。因此,智能指针通常被告知在多核架构上“不具有良好的可扩展性”。