This may be an eminently closeable question, but I'm the type that sees what sticks to the wall. For all of the benefits of memory and lifetime management afforded by a garbage collected runtime, have there been any notable cases of program indeterminacy caused by race conditions between an application and its garbage collector? Has a gestalt of defensive programming against this kind of thing emerged? Surely programmers accustomed to RAII must learn lessons when in the presence of GC.
I think you misunderstand how automatic garbage collection works. Race conditions between the application and a correctly implemented garbage collector aren't possible, even in principle. The garbage collector only collects objects that the application can't access.
Since only one of the two can ever "own" a given object, race conditions can't occur.
When I moved to the .NET world six years a go or so, I felt uneasy with the GC and I sort of took for granted that it should be much slower and that I was to be even more careful with my memory allocations to avoid producing performace hogs.
After six years I can tell you that my perspective has changed totally! I can only recall one time during these years that I've had a memory leak, due to a forgotten .Dispose(). Compare that to C++ where you produce a memory leak each hour of coding... ;-)
I have recenly been forced to return to the C++ world, and I'm totally flabbergasted! Did I use to work with this and like it once? It feels that I'm at least 10 times more productive in C# than in C++. And on top of that: the GC memory allocator is so blazingly fast that I still cannot believe it. Look at this question where I had to draw the conclusion that in my particular case, a .NET version (C# or C++/CLI) executed 10 times as fast as a C++ MFC version: C++ string memory allocation.
I have converted totally - but it took me a long time to fully accept it.
The problem with garbage collection is that it only manages memory resources. Unfortunately, programmers must manage many, many other resource types:
- file and socket handles
- database connections
- synchronisation objects
- gui resources
to name but a few. To manage those succesfully, you really need the concepts embodied in the RAII idiom.
When I first began programming in C I had to be very methodical with my malloc's and realloc's and I had to free everything I wasn't using. This was an easy task with tiny college assignments such as creating a binary tree. Simple...
Now when I started developing an application that had a GUI written in all C, I was having to think more and program less due to the fact that I have to pay attention to possible memory leaks. This was becoming a hassle. I would much rather have a half product than a half ass'd product.
I began moving over to Java and C#. I loved that all I had to do was dereference an object and the garbage collector would come along and pick it up for me. I have also noticed that my programs ran a bit slower using Java's Swing (as expected), but it was manageable.
In my findings, since processors are becoming cheaper and memory is becoming cheaper and faster, and GUI programs are consuming more memory than before. A garbage collector really helps with getting a product out that works with minimal issues with memory leaks. Really handy and can possibly lead to bad coding habits, however those can be remedied.
EDIT:
Also see this it may help you answer your questions. Good read IMO