On 9/25/07, ara.t.howard <ara.t.howard / gmail.com> wrote: > > i don't think i've ever noticed this behaviour: > > cfp:~ > cat a.rb > > class C > def self.count > c = 0 > ObjectSpace.each_object do |object| > c += 1 if self === object rescue next > end > c > end > end > > loop do > c = nil ### try with and without this!!!!!!!!!!!!!! > > (2 ** 16).times do > c = C.new > object_id = c.object_id > ObjectSpace.define_finalizer(c){ :nothing } > end > > puts "before: #{ C.count }" > > GC.start > > puts "after: #{ C.count }" > puts > end > > > > run both ways. notice that, without the prior declaration of c, the > code leaks like crazy: the finalizer itself holds a reference to the > object and prevents it being reaped. i don't think i've ever noticed > this behavior before. i understand it - but can this be correct? it > seems like you should be able to define a finalizer on any object > without preventing it from being gc'd! The usual way to do finalizers is class C def self.finalize(resource) lambda{ resource.free } end def initialize @resource = Resource.new ObjectSpace.define_finalizer(self, C.finalize(resource)) end end You can't GC the finalizer proc before running it, and you can't run it if there's a reference to the finalized object somewhere. Including the finalizer proc.