Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Any way to control order in which objects are GC'd?

3 views
Skip to first unread message

Lyle Johnson

unread,
Feb 22, 2001, 5:01:25 PM2/22/01
to
I fear that I already know the answer, but I'll go ahead and ask. But first,
the setup.

The problem is that for the Ruby extension module I'm working on, I'm
wrapping C++ objects that can have references (pointers) to other C++
objects. To avoid a problem of dangling pointers with circular references,
one would typically use this kind of pattern in the C++ class destructor:

// Destructor for SomeClass
SomeClass::~SomeClass() {
// clean up all outstanding pointers to me, because I'm about
// to be destroyed!
}

Ruby, of course, doesn't have the concept of C++ destructors. When the GC
detects that an object is no longer in use, it will get "collected". So the
problem I'm running into is that when object "Foo" gets garbage collected
(and the underlying C++ object "CFoo" is destroyed), there are still other
C++ objects out there that have references to "CFoo". As soon as they try
to access the recently deceased object, bad things happen.

So the question is, is there any way to control the order in which objects
get garbage-collected? For the current problem I'm debugging, all of this
action is taking place when the Ruby interpreter shuts down. For those
familiar with the source code, I'm looking at the function
"rb_gc_call_finalizer_at_exit()", which is defined in gc.c. The second loop
in this function loops over all the data objects and GC's them in an
arbitrary order.

Any suggestions are welcome...


Dave Thomas

unread,
Feb 22, 2001, 5:38:46 PM2/22/01
to
"Lyle Johnson" <ljoh...@resgen.com> writes:

> Ruby, of course, doesn't have the concept of C++ destructors. When
> the GC detects that an object is no longer in use, it will get
> "collected". So the problem I'm running into is that when object
> "Foo" gets garbage collected (and the underlying C++ object "CFoo"
> is destroyed), there are still other C++ objects out there that have
> references to "CFoo". As soon as they try to access the recently
> deceased object, bad things happen.

Would it be possible to have the Ruby GC manage you C++ objects? That
way you'd never have the problem, as an object with outstanding
references wouldn't get collected. Guy could answer this better, but
my impression is that the Ruby GC works with all the heap, and not
just objects it creates.


Dave

Ben Tilly

unread,
Feb 22, 2001, 6:10:56 PM2/22/01
to
"Lyle Johnson" <ljoh...@resgen.com> wrote:
[...]

>Ruby, of course, doesn't have the concept of C++ destructors. When the GC
>detects that an object is no longer in use, it will get "collected". So the
>problem I'm running into is that when object "Foo" gets garbage collected
>(and the underlying C++ object "CFoo" is destroyed), there are still other
>C++ objects out there that have references to "CFoo". As soon as they try
>to access the recently deceased object, bad things happen.
>
>So the question is, is there any way to control the order in which objects
>get garbage-collected? For the current problem I'm debugging, all of this
>action is taking place when the Ruby interpreter shuts down. For those
>familiar with the source code, I'm looking at the function
>"rb_gc_call_finalizer_at_exit()", which is defined in gc.c. The second loop
>in this function loops over all the data objects and GC's them in an
>arbitrary order.
>
>Any suggestions are welcome...
>
Well as you see, gc and reference counting are not friends.

So 3 suggestions.

The first is to stop using reference counting. (As already
suggested by Dave.)

That may not be easy, in which case you can map the idea of
destructors onto Ruby. Then in any block that you create
one of your objects in, call that in an ensure clause. Your
problem still exists, but if someone programs according to
your API, objects will be destroyed in a timely manner. (If
you have resources to clean up, this is the right approach
to take to cleaning them.)

The third option is to hack Ruby to have a way you can
register a collection of objects that need to be
destroyed first in the global destruction. Using WeakRef
you can register things in there without interfering with
them being garbage collected, and at the end of time you
know those things will go first.

Personally I would suggest the first or the second.

Cheers,
Ben
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com

Lyle Johnson

unread,
Feb 23, 2001, 9:15:20 AM2/23/01
to
> Well as you see, gc and reference counting are not friends.
>
> So 3 suggestions.
>
> The first is to stop using reference counting. (As already
> suggested by Dave.)

Dave & Ben,

Thanks very much for the discussion of the issues here. Actually, if I
understand the concept of reference counting, my problem is that the
underlying C++ library *doesn't* use reference counting! But at any rate, I
think the correct solution is going to be some modifications to the
underlying C++ library so that when one of these mutually dependent objects
get destroyed, the other one gets notified (so that it properly "forgets"
its reference). That way, the order in which Ruby's GC destroys the objects
won't matter anymore.

Thanks again,

Lyle

0 new messages