From: "Sean O'Dell" <sean / BUHBYESPAMcelsoft.com>
> In C++, I use the stack to create/destroy objects and if the objects
> themselves need to dynamically allocate large amounts of memory, I use
> the destructors to free up that memory. Garbage collection and the lack
> of destructor functions are a nightmare to me...it's those two features
> precisely that will keep me from using Ruby in any large projects.
> Don't get me wrong, I love Ruby to death, it's an amazing language...but
> garbage collection is terrorizing me...I can't abide memory usage
> building up to a critical point and then having this giant collection
> process kicking in, dominating my application.
[snip]
> I wish we could ditch it for stack-based memory management, with real
> object destructors to allow clean-up mechanisms for the dynamic memory
> allocations. But, I assume there's some fundamental design issues that
> would make that impossible.
Managing memory by allocating objects on the stack is fine, as long as
object lifetimes can be directly related to lifetimes of lexical scopes. In
my experience this is not often true in large applications, especially in
applications that have an object-oriented design. That's why C++ has the
new operator after all. However, if you want to do the same thing in Ruby,
use the "class allocates instance, passes instance to block, cleans up
instance" idiom to enforce an object lifetime to be the same as a lexical
scope. Of course, you have to be careful not to keep a reference to that
object outside the lexical scope, otherwise you end up with a dangling
pointer that references an invalid object. You can also explicitly call the
GC at the end of those scopes -- this will give you pretty much the same
behaviour as your C++ program.
Also, you can use finalisers instead of destructors. Compared to C++
destructors they are more flexible -- other objects can register a finaliser
on an object so that they can clean up their internal state when that object
is collected -- and safer -- you cannot get dangling pointers that
reference objects whose destructors have been called.
Finally, you shouldn't be terrorized by GC suddenly slowing your program
down. Empirical studies from around 10 years ago showed that conservative
garbage collectors had comparable performance to manual memory management --
for some applications GC was faster, for some slower, but on average the
same -- and garbage collectors have improved a lot since then. Manual
memory management can also take over your program at unexpected times; have
you ever looked at the amount of work malloc and free have to do to avoid
heap fragmentation, or how reference counting causes poor locality of
reference and thereby lots of cache misses?
Cheers,
Nat.
________________________________
Dr. Nathaniel Pryce
B13media Ltd.
Studio 3a, Aberdeen Business Centre, 22/24 Highbury Grove, London, N5 2EA
http://www.b13media.com