Dimitri said:
If a language is not garbage-collected, an unreachable
object is an error called "memory leak". I.e.
delete [] a;
a = null;
-- without "delete a" "a = null" is a memory leak.
GC eliminates memory leaks[0],
Actually GC doesn't eliminate memory leaks. The programmer no longer
needs to explicitly free objects before they become unreachable, but the
programmer is still responsible for making sure that an object *becomes*
unreachable when it's no longer needed. I've seen plenty of memory
leaks in large Java applications due to forgotten references to objects.
but it does that at the expense
of e.g. maintaining extra members in each object for reference
counting and/or code to iterate through objects and determine
their reachability, etc. -- dep. on GC scheme.
Once GC decides that "a" is not reachable it does the equivalent
of "delete a".
Hence my comment: the only way GC can be faster/more efficient
than explicit "delete a" is if it runs in negative time and
uses negative amount of memory. It eliminates a common class
of programing errors, yes, but claiming that it's more efficient
at the same time is like claiming you can eat your cake and have
it, too.
You seem to be claiming that in principle GC can't be faster than
explicit memory management, but there are a number of things wrong with
your argument.
Your argument seems to boil down to the claim that similar programs, one
using GC and the other explicit memory management, will need to perform
the same number of allocations and deallocations. Furthermore you seem
to be using the implicit premise that each allocation and deallocation
will take some fixed constant amount of time, regardless of whether GC
or explicit memory management is used. Therefore, at best GC could only
be as fast as explicit memory management.
I think one flaw in your argument is that you're assuming that malloc()
and free() run in constant time. If that were true, then it would be
hard to see how GC could be *much* more efficient than malloc/free. It
would still be possible for a particular GC to be more efficient than a
particular malloc/free implementation by some constant factor, but
that's it, since as you say the same number of allocations and
deallocations would still need to take place.
However, in fact malloc and free don't run in constant time. Behind the
scenes they need to maintain some sort of data structures that keep
track of memory blocks of different sizes, and try to allocate memory to
minimize fragmentation. The result is that malloc and free will take at
least O(log n) time, where n is the number of blocks being tracked. One
advantage some GC schemes have over malloc/free is that they can
defragment memory by moving allocated blocks around and coalescing free
blocks, thereby reducing the total number of blocks, and therefore speed
up allocations. Another advantage of defragmenting memory is it can be
used to reduce memory cache misses.
Another advantage for short running programs is that since GC can
postpone deallocations until it actually needs the memory, if the
program exits before needing more memory, those deallocations may not
even need to occur.
These are all theoretical advantages, but my point is to dispute your
claim that in principal GC can't be faster than explicit memory
management. In fact I've read several studies which show that GC is
often competitive or faster than manual memory managers with regard to
execution speed. However GC typically results in higher memory
requirements than explicit memory management, and less deterministic
execution speeds because a GC can occur at any time. So for certain
applications manual memory management may be necessary, but when
minimizing memory usage or deterministic execution speed aren't
requirements, then manual memory management seems like a waste of effort.
If you're interested in research on this subject, google for "automatic
explicit memory management comparison".
Adam