Hacker News new | ask | show | jobs
by pcwalton 4599 days ago
> You don't need finalization functionality in a GC'd language. If you imagine a language that lacks finalization functionality but has automatic memory reclamation, things turn out okay.

Not in fault-tolerant message passing systems, to name just one obvious example. Suppose that you put a bunch of file objects into a buffered channel, and then the goroutine that was supposed to receive those objects panics. Your program wants to recover from panics with recover(). Who closes the file descriptors in those channels? Nobody owns them yet: they were in a channel and the goroutine that was supposed to receive them died.

You might be able to solve this by handing out references to the channel to another goroutine that is supposed to clean up the file descriptors, but this gets really complicated. This sort of thing is why Go is GC'd in the first place. It's much easier to just have the GC clean up the file descriptors in channels in which one endpoint has gone dead, and that's the sort of thing finalizers are for and I assume it's the reason that finalizers were built into Go.

2 comments

one option is for the goroutine to defer a cleanup closure that closes every file in that channel. Panics will cause all deferreds to be called all the way up to the deferred which recover()s.

Another option is to crash the app instead of excessive recover()ing. (obviously there are good reasons to use runtime error handling, but imho fewer than what one would think).

Have the things in the channel be the equivalent of C#'s IDisposable or something, then the goroutine can clean them up itself.
Have you read pcwalton example?

How can the goroutine clean them if it is dead?

Sorry, the words coming out of my fingers didn't match the thought in my mind. The channel can dispose of them.