Monday, January 19, 2009

Garbage collection - it's not about lazyness

There seems to be a common belief amongst a number of Delphi programmers (and c++ programmers etc) that garbage collection is all about being too lazy to do your own clean-up.

E.g. Babnik asks "What is it about Garbage Collection?" (kudos for actually asking the question) and his post has the implicit assumption that advocates are trying to avoid doing a bit of minor work.

Others have posted far more stronger comments (check the responses to Babnik's post) straight out stating that gc = lazyness, bad coding and a slack attitude to life. I find this attitude condescending and offensive. The reason I want gc, is not because I write bad code, but because i want to write better code.

I would like to see garbage collection in native Delphi, not as a mandatory feature, but as an option. It's not something I am holding my breath for, but if there was one thing I could add, that would be it.

I know I am repeating myself, but here are my main reasons for wanting a gc (expanded from an earlier post on the subject):

  • Better code: In a non gc language, you end up with a number of idioms and practices to guard against memory leaks. Delphi has several of these.
    E.g.:
    It is rare to return an object from a function. Typically you would create an object and then pass it to a procedure to be modified.
    The use of assign rather than :=
    The use of Owner, Owned and the like to solve object destruction problems)

  • Less code: I performed a naive analysis on my most recent project by removing most .Free calls and the supporting destructors and try … finally blocks. The result was about 4% fewer lines of code. More importantly, the code I removed was boring, boilerplate which solved no business problems and added no value (other than preventing leaks)

  • Faster development: There are some minor time savings to be had simply by typing less code. However when I was regularly programming in c# I found my productivity improved due to the change of coding style that gc allowed.

  • Fewer memory leaks: By reducing the need for manually freeing memory, a gc significantly reduces the scope for memory leaks. It is still possible to leak memory, but much harder.
  • There are some problems that it is difficult to solve without a GC. Linq is often given as an example. Class operators (as opposed to record operators) is another
One of the main reasons I see for Delphi to have a gc, is that it's competitors have it. If we are to persuade people to write applications in Delphi as opposed to C#, Java etc then requiring manual memory is at best a speed bump.

Finally garbage collection definitely falls into the "Your kilometreage may vary" category. If you are working in memory constrained environments then manual management is the way to go. If you are writing database driven business apps or web apps (as I usually am) then manual management offers little or no advantage over a garbage collector.

10 comments:

Anonymous said...

If you really need gc in Delphi, why not using Delphi Prism?
In my opinion it is great that native Delphi is different then its competitors.
Furthermore, it gives you a choise using the best/proper tool for your projects.

Anonymous said...

In fact, using Smart Pointers gives you the advantages of a non-gc environment (i.e. if you want, you can know when objects will be destroyed) and the advantages of a gc one. I just need to guard against circular references (like gc).
Using gc is not only about "garbage collection". GC's usually can move objects, use Handles (i.e. 3 levels of indirection) instead of pointers,etc...
And in a native world would be hard to pass gc objects to other native functions (i.e. C++ classes, win32,etc...)

I won't like to be forced to use gc, but I understand that making it an optional features would not be possible.

So, I agree that if you want gc, just use .NET ,else use Smart Pointsers.

Anonymous said...

Given the gains you cite, by your own admission, GC sounds like nothing more than a poor form of premature codelines optimization.

This is compounded by the fact that GC gains are all theorical, and never seen in real-world applications: GC languages exhibit neither less bugs, nor higher performance, and their line count is similar enough.
Memory leak in itself IS NOT an issue, it's memory over-used, whil the application is running and stressed. In GC apps that means not nil'ing reference or not disposing of resources early, and it is a highly common issue since none of the GC apps' code cares about it.

Sean said...

@anon1

I am planing on using prism for a few projects. New web apps will probably be done in prism or c# for a starter. However I won't be doing desktop apps in prism, I prefer native code for those.

However using Prism just to get a gc is like buying an American car just to get an automatic gearbox. Sometimes (not always, just sometimes) I would like the automatic option without having to change makes and models.

I don't need a gc, I would like one. There is a substantial difference.

@QbProg
Smart pointers will give some of the thngs that i want from gc, and I am planning on using them more as I move my projects to D2009.

It is possible to have optional gc, D does just that.

@Anon2
I have reread my most and your comments and I am not sure what parts you are referring are premature optimisation. You could as easily argue that writing more code to manually manage memory is a premature optimisation. In my view, writing better code is never premature.

It is very hard to compare lines of code between dissimilar languages. C# requires fewer lines of code than c++, but I doubt that has anything to do with the presence or absence of a gc. Similarly with performance, there is more to benchmark differences between languages than the memory management techniques. In the case of the database driven applications I mostly write, any performance impact due to using a gc would be swamped by the database access time.

@All
My post was not called "This is why Delphi must have a gc", it was called "Garbage collection - it's not about lazyness". I am not really interested in debating if delphi native should have a gc (it won't in the near future), but in debating the apparently entrenched idea that to use a gc is a sign of lazyness.

Anonymous said...

I see the only reason for GC in Delphi - the future support of functional programming concepts, but I would prefer to see these things done with native managed code, without GC.

Anonymous said...

"I just need to guard against circular references (like gc)."

just FTR, proper GC (such as in .NET) has no problems with circular references. as long as two (or more) objects aren't reachable from the root, they can reference each other as much as they please, GC will still collect them.

Anonymous said...

When I switched to C#, my productivity increased because of:

- Better help (VASTLY better)
- Better intellisense
- Better code completion
- Lots of little things, like autoindenting, begin-end bracket pair highlighting, no VAR block requirements, no Initialize/Implement block co-ordination, simpler property get/set concept, better refactoring...

GC was way down the list.

Anonymous said...

...oh, and more informative tooltip style hints over functions; and ESPECIALLY being able to create your own for your own functions, REALLY is a productivity booster!

Anonymous said...

Garbage Collection <> lazyness, but GC leads to lazyness. In every implementation I've used (Java, .NET), significant numbers of objects must still be manually disposed (in .NET, they implement IDisposable). Yet, the number of times I see code that fails to properly dispose of objects makes my head spin (Streams are classic examples).

Programmers, almost by definition, ARE lazy, and GC seems to encourage their nasty habit of not considering resource usage and lifetimes of the code they write.

Diogenes Fluye said...

Awesome blog yyou have here