2010-02-23

Garbage collection considered harmful

I think garbage collection is one of the biggest disservices modern programming languages brought upon us. It is touted as a silver bullet and apparently no new language can live without it. Java, Python, PHP, ActionScript, VisualBasic, C#, Ruby, ...

Why do I think garbage collection is evil?
  • the problem it promises to solve isn't actually solved. You can still easily get memory leaks by building circular references or forgetting to unregister event handlers. However now these leaks are much harder to track down and fix.
  • the problem of memory management, i.e. efficiently using the available memory is made tremendously harder. You give up all control over when or even if your objects get collected. There is no easy way to make use of the problem domain knowledge the programmer has and the garbage collector hasn't. If I know in advance I'll need a lot of memory the next frame it makes sense to clean up ahead of time. The garbage collector can't know this and will be caught off guard, causing performance drops. Also, how much memory is wasted for "zombie objects", that just linger around, waiting to be collected? Trying to fine tune an application's memory profile and reducing it's footprint feels like having to work blindfolded, in a straight jacket with your feet stuck in the mud.
  • as far as I know no one has figured out yet how to combine garbage collection with deterministic destruction. Destructors in garbage collected languages are either non-existent or worthless because you don't get any guarantees when or if they'll execute. This kills one of the most useful programming idioms ever invented: RAII, or Resource Acquisition Is Initialization. You acquire a resource in a class' constructor and release it in the destructor. There is a well defined sequence of events and the destructor is guaranteed to be called, you cannot forget to release the resource. And before you say garbage collection makes alloc/release patterns obsolete think again. There are other resources besides memory that follow the exact same pattern with potentially catastrophic consequences if you forget to release them: file handles, network connections, vertex buffers, audio loops, database connections, database transactions, locking textures, mutexes... I'm sure you can think of more. And this is not even accounting for application specific logic like undo/redo patterns.
  • this is related to the previous point about RAII. Without deterministic destructors writing exception safe code becomes very hard indeed. Instead of having all your classes clean up automatically after themselves you have to manually remember to bracket everything with try/catch/finally clauses. As a direct consequence you'll need absolute information about what code may throw exceptions and when. Knowledge that often has nothing to do with the problem at hand, is easily forgotten and is often buried under layers and layers of code. Hence Java-like crutches of requiring exception specifications for every method.
  • you lose value semantics for everything but the simplest native types. There is a distinct divide between native types like int and objects. While the former are passed around by value the latter can only be passed by reference. This causes lots of confusion and ugly hacks (Java's int vs Integer) and often forces you to write less efficient code.

Contrary to popular belief memory management is not a problem in C++. In fact, in modern C++ you hardly ever allocate memory directly. I can't remember the last time I had to search for a memory leak but I do have to minimize memory usage of my programs constantly. Yes, even in times of multi gigabyte RAM machines you easily exhaust that memory when dealing with lots of concurrency or just large complex problems. Now garbage collection solves a problem I don't have (leaking memory) while making a problem I do have (using too much memory) infinitely harder to solve. And before anyone says I just haven't discovered my leaks yet - some of my stuff has to run 24/7 under heavy load, even small leaks will quickly become apparent in such a situation.

Trusting the garbage collector to solve memory issues for you is like sitting in a burning house, closing your eyes to the problem and repeating to yourself: "Everything's gonna be fine. Everything's gonna be fine." until you go up in flames. Memory leaks aren't the problem, using too much of it is.

Summary: I hate garbage collection and the sooner the world rids itself of that addiction the better.