This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.
A couple of years ago, I wrote a set of three essays on Resource Management: The Semantics of Garbage Collection, More Thoughts on Resource Recovery, and Other Resource Recovery Approaches.
In summary, my argument in these articles was that the standard mark-and-sweep garbage collection falls down for two major reasons, it doesn't deal with any resources other than memory and it fails to account for object lifetime issues.
Recently, a comment showed up on the Artima forums that shows that I'm not the only one to wonder about these issues: Java Community News - When GC is Not Enough: Resource Management in Java. This comment was inspired by the article Java theory and practice: Good housekeeping practices. Both the article and the comment discuss handling resources other than memory and how important it is to be careful in your resource management.
I find amusing the advice to be careful with memory management in a context where garbage collect is used to remove the need for memory management. Aren't these two issues essentially the same thing? I can't count the number of times I've been told that garbage collection is required because ordinary programmers can't be trusted to manage memory correctly. (An argument that I don't particularly agree with despite examples proving the point.) If the argument holds for memory, why doesn't it hold for file handles and database connections? I would argue that it doesn't really hold for memory either.
I don't believe that garbage collection solves the memory management problem any more than it solves the resource management problem. I think that programmers should be accountable for managing both memory and resources. While we don't want to do this manually, giving up the ability and responsibility completely is not the answer. A better solution would be to have tools that support resource management without giving away the ability to manage them.
One of the most useful idioms in C++ is Resource Acquisition is Initialization (RAII). The key concept is tying the ownership of each resource to an object and using the object lifetime to determine when the resource is in use. Unfortunately, the normal mark-and-sweep garbage collector implementation discards the concept of defined object lifetime, so we don't have that ability in a language depending on that form of GC. In fact, Goetz refers to that issue when he talks about the problems with finalizers in the Good Housekeeping article cited above.
Unfortunately, the only solution in a language without defined object lifetimes is to explicitly manage the resources everywhere they are used. Both Goetz and one of the comments in the forum point out that using a try - finally
allows you to force this cleanup to happen correctly. Unfortunately, what neither of them mention is that this violates the DRY principle (Don't Repeat Yourself). Now, everywhere you use a particular resource you will need to copy this identical piece of code. This repetition is almost guaranteed to be a source of bugs.
While I agree that memory management in a language without garbage collection is harder than it needs to be, I still maintain that classic garbage collection is not the solution. Unfortunately, I suspect that the advocates of mark-and-sweep will either continue to ignore the issue or try to force some unnatural connection between other resources and memory. This way they can apply their favorite hammer to the job.