开发者

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. Yes, Stroustrup tried this on and has repeatedly failed not because of technical issues but because of conformance issues. 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. 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). 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 d开发者_开发技巧efine a new language if we want automatic transparent memory management.

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.

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.

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.

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; as is done in 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. 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.

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.


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?" 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."

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++. 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#.

Go ahead, downvote away...


"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. Use the right tool for the right job and life is much easier.


Can I prove you wrong by giving examples of optional transparent garbage collectors for C++?

  • boehmgc
  • libgc

There's also a good discussion on the Boehm site that should be required reading for questions like this.


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>?

You need to consider the genuine purpose of a 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. Why not just have a std::gc_new? We already have a std::make_shared.

And, in C++0x, it is already implementation defined whether or not undeleted objects are deleted automatically.


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.

To do that, the GC needs to be able to traverse the object graph. 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.

In C++, there is usually no such thing. 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.

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.

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜