Re: Garbage Colletor
- From: Peter Duniho <NpOeStPeAdM@xxxxxxxxxxxxxxxx>
- Date: Wed, 10 Oct 2007 14:05:08 -0700
Larry Smith wrote:
It's a religious issue and both have their pros and cons. While C++ may be
more error-prone than a GC system however (for releasing resources), there
need not be a significant difference.
I certainly agree there. But one system is definitely more resilient to programmer error.
The problem is almost entirely a human
one. It's extremely easy to handle resources in C++ as you stated but the
language's reputation has often suffered because of its practioners (most
programmers being very poor at what they do). My own opinion however is that
in the hands of those who really know what they're doing (few and far
between),
I think we've found ourselves in vehement agreement on that point previously. I'm still in vehement agreement with you on it. :)
RAII is a cleaner approach than a GC system. By clean I mean it's
more natural to release your resources in a destructor than to wait for a GC
to run (not to be confused with easier or less error prone - it's clearly
not).
Well, the thing is...once you no longer have a reference to a memory resource, it _is_ released. Just because the GC hasn't run, that doesn't mean the memory isn't available. It just means that the GC hasn't gotten around to moving it into the collection of memory that is _immediately_ available for use.
Logically speaking, the memory is still in fact available, the moment you release your last reference to it.
The "using" statement for performing this in C# for instance (or even
worse, a "finally" block), is ugly compared to a C++ destructor.
IMHO, it's a mistake to think of the "using" statement, the finalizer, or IDisposable as related to a C++ destructor. It's only "ugly" compared to it if you are treating them the same.
The "using" statement and IDisposable exist for one purpose: to explicitly release resources held by an object without releasing the object itself. Within that one purpose, there are two sub-categories of types of resources that may be released: managed, and unmanaged.
Obviously the only reason the unmanaged category even exists is that ..NET runs on top of a system that is not entirely managed code. If all of Windows was based on a garbage collection system, that category wouldn't exist.
So, let's consider only the managed category. In this case, it's beneficial to be able to tell an object "let go of the resources you're holding" without releasing that object itself. But this is again not comparable to a destructor, because the object itself still exists. It hasn't been released or destroyed and it is theoretically possible that it could be reused. This is much more comparable to a C++ class that hasn't been deleted, and thus hasn't been destroyed, but which has some sort of "release your resources" function that has been called.
The destructor is nicely symmetrical with its constructor.
The latter initializes the object and the former cleans it up.
And in C# not having a reference to an object is nicely symmetrical to creating a reference to an object. The latter initializes the object and the former cleans it up. In a purely managed environment, releasing a single reference to an object is exactly equivalent to the C++ paradigm of having to call a destructor where individual resources within the object have to be explicitly cleaned up.
In fact, the garbage collection model is, at least for that particular operation, much more efficient, because there's no need to go through the entire object cleaning things up. Everything that object refers to is automatically released, with a single nulling, or leaving scope, of the last variable holding a reference to that object.
Overall, I suspect the efficiency is about the same. The extra work that the C++ model has to do initially is balanced by the extra work the garbage collector will have to do later.
This occurs immediately
when an object goes out of scope so your resources only exist for as long as
they're needed.
Likewise, using GC as soon as an object is no longer referenced, any managed resources no longer exist. They are automatically released when that object referencing them is.
It's all very well controlled and understood. You know
exactly when clean up is going to occur and need not worry the timing of a
GC.
But why do you care when the GC is going to occur? It only happens when it needs to, or when it gets the opportunity to, and there should be nothing in your code that depends on or otherwise relies on when, if at all, garbage collection happens.
In a multi-tasking operating system like Windows, there are a wide variety of things that occur and which you have no control over. A garbage collection system simply introduces a new instance to this already very broad category of components.
In fact, a GC itself can even promote sloppy behaviour. People become
so used to it doing the clean up that they can neglect to explicitly clean
something up themselves when the situation calls for it
I don't understand that at all. A person who isn't used to releasing a reference to an object when they are done with it isn't going to be used to deleting a C++ object when they are done with. Conversely, a person who can remember to delete a C++ object when they are done with it can remember to release a reference to a .NET object when they're done with it.
(such as immediately
releasing a resource that might later cause something else to fail if it
hasn't been GC'd yet).
What kind of resource? If you're talking about a managed resource, then simply releasing the reference to the referencing object is sufficient to release the resource.
If you're talking about an unmanaged resource, well...that's not a problem inherent with garbage collection. It's a natural consequence of mixing a garbage collection system with a traditional alloc/free system. That problem _only_ exists because of the traditional alloc/free system; it hardly seems fair to blame it on the garbage collection paradigm.
Or people might always perform shallow copies of
their objects where a deep copy is required (since it's just so easy).
This one I understand even less. If a deep copy is required but a shallow copy is done, this is if anything more dangerous in the C++ model, because the referenced data can be freed by any one copy of the instance. This just won't happen in a garbage collection system.
With a GC system, you still have the potential issue of having multiple instances refer to the same data, but this issue exists regardless of the memory management model. It's an implementation problem, not a memory management problem.
In
C++ you have to think about these things more but that deeper thinking
process also sharpens your understanding of the issues IMO (and hopefully
the design of your app). Of course this is all a Utopian view of things. In
the real world most programmers require the handholding that a GC offers.
I generally agree that it is good to think more deeply about what is going on. A person who understands better the lower levels is almost always going to be able to use use the higher level API more effectively. But I don't see how that makes the C++ model necessarily better; either model has some lower level implementation details that are important to understand for most effective use, and C++ has just the same potential for someone failing to bother to learn those lower level implementation details as .NET does.
And I still think that people scoff at garbage collection at least as much as they do the more traditional C++ model.
Pete
.
- Follow-Ups:
- Re: Garbage Colletor
- From: Ben Voigt [C++ MVP]
- Re: Garbage Colletor
- From: Larry Smith
- Re: Garbage Colletor
- References:
- Garbage Colletor
- From: Johnny E. Jensen
- Re: Garbage Colletor
- From: Peter Duniho
- Re: Garbage Colletor
- From: Chris Mullins [MVP - C#]
- Re: Garbage Colletor
- From: Larry Smith
- Re: Garbage Colletor
- From: Peter Duniho
- Re: Garbage Colletor
- From: Larry Smith
- Re: Garbage Colletor
- From: Peter Duniho
- Re: Garbage Colletor
- From: Larry Smith
- Garbage Colletor
- Prev by Date: Re: Get Error Number
- Next by Date: RE: EventLog settings
- Previous by thread: Re: Garbage Colletor
- Next by thread: Re: Garbage Colletor
- Index(es):
Relevant Pages
|