From: Nat Pryce Date: 2001-08-13T19:22:43+09:00 Subject: [ruby-talk:19630] Re: Forced garbage collection From: > In ruby, the finalizer runs *after* the object is GC'ed. There is no > more object, so the funky "save the object reference in a global" > problem can't happen. So, how do we get to the data formally stored > in that object? Well, that's what the block closure is for. We make > sure we create the closure in such a way that it "remembers" anything > we need to dispose of at finalization time. This also means that we > had better be careful not to accidently create a reference to the > object. 1) It won't be there when finalization is done, and 2) the > reference keeps the object from being collected. Excellent explanation. Thanks. I've got my WeakHash working now. The way to avoid holding a reference to the object in its finalizer is to use a factory method to create finalizers. That method should take as arguments all the data required to finalise the object, but *not* a reference to the object itself. Therefore the closure does not refer to the object and so will not keep the object from being garbage collected. E.g. from my WeakHash: def []=( key, value ) @hash[key] = value.__id__ ObjectSpace.define_finalizer( value, create_finalizer(key) ) end def create_finalizer( key ) proc { |id| remove_key(key) } end def remove_key( key ) @hash.delete( key ) end