"Java, for instance, implements a memory management system known as automatic garbage collection. In this system, the developer does not need to worry about actively de-allocating unused objects, rather a hidden garbage collector checks each object to see whether or not it is being used by other objects...."
The use of "hidden" is quite misleading. In most GCed systems (I don't know Java, so if this is a Java specific point...well, so much the worse for Java), garbage collection can be explicitly triggered (e.g., in Squeak by "Smalltalk garbageCollect.") and high end Smalltalk and Common Lisp systems (for example) there are lots of aspects of the GC which are exposed to the programmer for tuning purposes (e.g., you can adjust the size of various spaces, put some objects in a non-scanned "permanant" space, or even change the entire GC strategy).
Then you wrote:
"Objective-C uses another form of memory management known as "reference counting." In this system, each object is associated with a count of how many other objects are currently using it, but the reference counts of objects in an application must be actively managed by the developer."
To be accurate this is *manual* reference counting. It's perfectly possible to use a reference counting strategy as an *automatic garbage collection* technique. Perl and Python do this. RC and automation are orthoganal issues.
Then you wrote:
"Both of these memory management schemes have advantages and disadvantages. Automatic garbage collection is easy on the developer because it's entirely automatic. However, this convenience comes at the expense of performance and efficiency."
This is highly tendentious at best. GC strategies (and their implementation) vary widely in their performance characteristics and how well they do often depends *a lot* on the application in question. *Lifetime* costs to an application run for a stop and copy collector can be very low (although there might be undesirable effects, like long pauses...these are undesirable for (many) *interactive* programs, but might be quite reasonable for a scientific modeling program where overall time saved is more important than avoiding pauses). Furthermore, different collection strategies enable different (often more efficient) allocation strategies, or can help locality, etc. etc.
A naive RC (manual or otherwise) can perform *way* worse. One simple example is if your code contains lots of cyclic data structures. Or if the references to many of your objects fluctuates rapidly (so your ref counts are constantly and pointlessly being altered).
Now there are clever ways around this, but they have their tradeoffs as well.
"Reference counting on the the hand is very efficient and fast because there is no garbage collector working behind the scenes using up resources."
I take it that the above points amply demostrate how silly this is.
For futher reading I recommend the following:
Paul Wilson's large GC survey: http://www.cs.utexas.edu/users/oops/papers.html#bigsurv
Richard Jones' book and list of links: http://www.cs.ukc.ac.uk/people/staff/rej/gc.html
Or just do some simple research. Googling about will help.
There were some neat discussion of RC vs. other strategies on comp.lang.lisp. For example:
Really, that whole thread.
Now, RC strategies of various sorts *do* have interesting properties that can be useful in various situtations, but it's irresponsible to pass on the "convenience vs. performance" myth. The grounds for deciding are *far* more complicated.