From: Robert Klemme Date: 2005-06-20T06:25:35+09:00 Subject: Re: GC.disable not working? "Robert Klemme" schrieb im Newsbeitrag news:3hm4olFhoppnU1@individual.net... > > "ts" schrieb im Newsbeitrag > news:200506191610.j5JGAeIU001389@moulon.inra.fr... >>>>>>> "E" == Eric Mahurin writes: >> >> >> E> I tried this on 1.8.2 and a 1.9 CVS version. In both it calls >> E> the finalizer when GC is disabled (GC.enable==true). I thought >> E> this would be impossible. I also get a recycled object error. >> >> it's normal : the finalizer is called when ruby stop and it don't care at >> this moment if the GC is enabled or not. > > They can be invoked before termination of Ruby. But it's guaranteed that > all finalizers are called before exit. > >> E> Any clues to what is going on with this GC stuff. If I can't >> E> get this to work, I don't see how anybody reliably use >> E> ObjectSpace._id2ref. >> >> it's best to don't use _id2ref > > I beg to differ: you can safely use _id2ref in conjunction with > finalizers - it just has to be done properly. It will go wrong - as > demonstrated - if the same collection that stores ids is used for > iterating / querying. To avoid any confusion let me add some clarification: _id2ref has its uses, but some caution has to be applied: - don't use it in finalizers - if objects might have been collected, take precautions (i.e. catch exceptions) Also, WeakReferences can be used in many places if you want to be able to refer an instance but don't want to prevent garbage collection (storing an oid often serves the same purpose). The example of course does not show the usage of _id2ref. You can add a method like this to class Foo: def self.list FOO.each do |oid, x| begin p ObjectSpace._id2ref(oid) rescue RangeError => e puts "#{oid} collected but not finalized: x=#{x.inspect}" end end end > This approach works ok - you'll have to imagine that x contains > information needed for proper cleanup of a Foo instance, for example, an > open IO instance (although I'm sure that will do proper cleanup on > finalization): > > class Foo > FOOS = {} > > def initialize(x) > self.x=x > > ObjectSpace.define_finalizer(self) do |oid| > puts "Cleanup of #{oid} with #{FOOS[oid]}" > end > end > > def x=(y) > @x = y > FOOS[object_id] = y > end > > def x() @x end > end > > Kind regards > > robert >