简体   繁体   English

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

[英]Why can't C++ have an optional transparent garbage collector

There's a related question but this one is slightly different and I'm not happy with any of the answers to the related question :) 有一个相关的问题,但这个有点不同,我对相关问题的任何答案都不满意:)

I'm going to ask this question in the negative by asserting it is not possible to have an optional transparent garbage collector for C++ and hoping someone will prove me wrong. 我将通过断言不可能为C ++提供可选的透明垃圾收集器并希望有人证明我错了,从而对这个问题提出质疑。 Yes, Stroustrup tried this on and has repeatedly failed not because of technical issues but because of conformance issues. 是的,Stroustrup尝试了这一点并且一再失败,不是因为技术问题,而是因为一致性问题。 Performance is not an issue here. 性能不是问题。

The reason C++ will never have such a collector is that being optional a program which runs without the collector must implement all the required memory management manually. C ++永远不会有这样一个收集器的原因是,在没有收集器的情况下运行的程序是可选的,必须手动实现所有必需的内存管理。 Adding a collector may then provide some performance benefits, but it isn't clear they're worthwhile (yes, a collector can be faster). 添加收集器可能会带来一些性能优势,但不清楚它们是否值得(是的,收集器可以更快)。

What you cannot obtain is automatic memory management, which is the principal reason for desiring a collector. 你无法获得的是自动内存管理,这是渴望收集器的主要原因。 You would get this with mandatory collection (without necessarily sacrificing RAII or other things if you choose to do correct manual management). 您可以通过强制收集获得此功能(如果您选择进行正确的手动管理,则无需牺牲RAII或其他内容)。 A mandatory collector with optional manual memory management is tenable. 具有可选手动内存管理功能的强制收集器是可行的。

Unfortunately, the only way to get a mandatory collector creates an incompatibility with earlier versions of C++ not using a collector: in other words we have to define a new language if we want automatic transparent memory management. 不幸的是,获得强制收集器的唯一方法是创建与不使用收集器的早期版本的C ++不兼容:换句话说,如果我们想要自动透明内存管理,我们必须定义一种新语言。

So my contention is: C++ will never have garbage collection because it is locked into a historical development which requires upward compatibility: mandatory collection with optional manual memory management is viable but transparent optional garbage collection is not. 所以我的论点是:C ++永远不会有垃圾收集,因为它被锁定在需要向上兼容的历史开发中:强制收集和可选的手动内存管理是可行的,但透明的可选垃圾收集不是。

Prove me wrong by exhibiting a tenable optional transparent garbage collection model! 通过展示一个可选的透明垃圾收集模型证明我错了!

EDIT: 编辑:

Oooo .. I think I have the answer. 噢..我想我有答案。 Can someone quote the Standard where it requires programs to delete heap allocated objects? 有人可以引用标准,它需要程序删除堆分配的对象吗?

Because: that clause, if it exists, is the only thing stopping optional transparent garbage collection. 因为:该子句(如果存在)是唯一阻止可选透明垃圾收集的子句。 There may even be enough time to get that clause removed from C++1x. 甚至可能有足够的时间从C ++ 1x中删除该子句。

Without such a clause, a program can leak memory without the behaviour being undefined: the behaviour when out of memory is just the same as it usually is. 如果没有这样的子句,程序可能会泄漏内存而不会出现未定义的行为:内存不足时的行为与通常情况相同。 And so tacking on a garbage collector will do nothing to the specified semantics: they're well defined or not, independently of whether the collector is used or not. 因此,对垃圾收集器执行操作将不会对指定的语义执行任何操作:它们是否定义良好,与是否使用收集器无关。

Prove me wrong by exhibiting a tenable optional transparent garbage collection model! 通过展示一个可选的透明垃圾收集模型证明我错了!

See: C++/CLI . 请参阅: C ++ / CLI

The difficulty with putting a garbage collector with existing C++ code is that C++ often relies on deterministic object destruction in order to make things happen; 将垃圾收集器与现有C ++代码放在一起的困难在于C ++通常依赖于确定性对象破坏以使事情发生; as is done in RAII. 正如在RAII中所做的那样。 Sure, the garbage collector would be able to make most kinds of memory RAII transparent, but plenty of RAII related concepts don't have anything to do with memory. 当然,垃圾收集器能够使大多数类型的内存RAII透明,但是大量与RAII相关的概念与内存无关。 For example, sockets, streams, and locks all are amenable to some form of RAII management, and none of these would work well if deterministic destruction was not preserved. 例如,套接字,流和锁都适用于某种形式的RAII管理,如果不保留确定性破坏,这些都不会很好。

Therefore, it probably won't be "transparent" -- it'd have to be something like C++/CLI where you have to say "I want this to be garbage collected" -- but it's by all means reasonable and possible. 因此,它可能不会是“透明的” - 它必须是像C ++ / CLI这样的东西,你必须说“我希望这是垃圾收集” - 但它绝对是合理和可能的。

This may be better suited as a comment rather than an answer, and may draw many downvotes. 这可能更适合作为评论而不是答案,并且可能会引起许多暗示。 So be it. 就这样吧。

Whenever someone asks a question like "Why can't C++ have GC?" 每当有人问“为什么C ++不能使用GC?”这样的问题时。 I think to myself "because I don't want your damned garbage collection. I want to control when objects live. I want to control when objects die. I want destruction and deallocation to be deterministic, not based on some hokus pokus black magic. I don't need GC to write better programs. Therefore, GC will do nothing for me but get in my way." 我想自己“因为不想要你那个该死的垃圾收集。我想控制物体何时存在。我想控制物体何时死亡。我希望破坏和释放是确定性的,而不是基于一些hokus pokus黑魔法。我不需要GC来编写更好的程序。因此,GC对我没有任何作用,但会妨碍我。“

But even beyond that, consider this. 但即便如此,请考虑这一点。 C# and the other .NET languages have GC built in. The compilers and the CLR for these languages were written primarily in C++. C#和其他.NET语言都内置了GC。这些语言的编译器和CLR主要是用C ++编写的。 This includes the memory management facilities, except for a few performance-critical pieces written in assembler. 这包括内存管理工具,除了一些用汇编语言编写的性能关键部分。

So you might say that anything that C# can do, C++ can do, since C++ begat C#. 所以你可能会说C#可以做的任何事情,C ++都可以做,因为C ++生成C#。

Go ahead, downvote away... 继续,向下走

I think that you're taking the wrong approach. 我认为你采取了错误的做法。 There's no reason that a GC should be transparent- why not have a std::gc_pointer<T> ? GC没有理由透明 - 为什么没有std::gc_pointer<T>

You need to consider the genuine purpose of a GC. 您需要考虑GC的真正目的。 This isn't to solve memory management, because the existing smart pointers (in C++0x) solve this just fine - it's to offer a different performance characteristic to manual memory management, that's very suitable for temporary allocations. 这不是为了解决内存管理问题,因为现有的智能指针(在C ++ 0x中)解决了这个问题很好 - 它为手动内存管理提供了不同的性能特性 ,非常适合临时分配。 Why not just have a std::gc_new? 为什么不只是有一个std :: gc_new? We already have a std::make_shared. 我们已经有了一个std :: make_shared。

And, in C++0x, it is already implementation defined whether or not undeleted objects are deleted automatically. 并且,在C ++ 0x中,已经实现定义是否自动删除未删除的对象。

"Why doesn't my Lamborghini have a snow plow blade mount?" “为什么我的兰博基尼没有雪犁刀座?” Because it's not designed for snow removal ;) 因为它不是为除雪而设计的;)

C++ wasn't designed like C# and has different uses. C ++的设计并不像C#,具有不同的用途。 Use the right tool for the right job and life is much easier. 使用合适的工具来完成正确的工作,生活更轻松。

The real problem is not so much ensuring object destruction happens deterministically (that could probably be done without too much trouble: when an object goes out of scope (or delete is called in the case of heap-allocated objects), its destructor can be called, while the actual reclaiming of memory can be left until a later garbage collection) -- but rather how to identify what to collect. 真正的问题不是确保对象破坏确定性地发生(可能没有太多麻烦地完成:当一个对象超出范围(或者在堆分配的对象的情况下调用delete )时,可以调用它的析构函数,而实际内存回收可留到以后垃圾收集) -而是如何识别要收集

To do that, the GC needs to be able to traverse the object graph. 为此,GC需要能够遍历对象图。 In "properly" GC'ed languages, that's simple enough, as every object is tagged with a type pointer of some kind, allowing the GC to know the structure of the object it is visiting. 在“正确”的GC语言中,这很简单,因为每个对象都用某种类型的指针标记,允许GC知道它正在访问的对象的结构。

In C++, there is usually no such thing. 在C ++中, 通常没有这样的东西。 There is no way for the GC to know whether the word it is looking at is a pointer or not, and equally important, whether or not the next word is part of the same structure/array, or if it is unallocated. GC无法知道它所看到的单词是否是指针,同样重要的是, 下一个单词是否是同一结构/数组的一部分,或者它是否未分配。

Of course, the standard doesn't prohibit an implementation from adding such type information, but that would carry a cost in runtime performance and memory usage, which is incompatible with C++'s "you only pay for what you use" philosophy. 当然,该标准并没有禁止实现添加这样的类型信息,但这会在运行时性能和内存使用方面带来成本,这与C ++的“你只为你使用的东西付费”的理念是不相容的。

An alternative option, taken by the GC's that exist, is to implement a conservative GC, which might not reclaim all memory, because it has to guess at whether a word is a pointer or not, and when in doubt, it has to be pessimistic. 存在的GC采用的另一种选择是实现保守的GC,它可能不会回收所有内存,因为它必须猜测一个单词是否是一个指针,并且当有疑问时,它必须是悲观的。

Can I prove you wrong by giving examples of optional transparent garbage collectors for C++? 我可以通过为C ++提供可选的透明垃圾收集器示例来证明您的错误吗?

There's also a good discussion on the Boehm site that should be required reading for questions like this. 对于Boehm网站有一个很好的讨论,需要阅读这样的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM