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!
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.
···
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!
yeah - trying to prevent the closure... smart. i'm not having luck though:
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
def nothing
end
loop do #c = nil ### try with and without this!!!!!!!!!!!!!!
(2 ** 16).times do
c = C.new
ObjectSpace.define_finalizer c, &method(:nothing)
end
puts "before: #{ C.count }"
GC.start
puts "after: #{ C.count }"
puts
end
again, if you un-comment the 'c = nil' line it'll work, but avoid the closure alone doesn't work on my platform. does it work for you? did i misunderstand your comment perhaps?
On Sep 25, 2007, at 10:14 AM, Sylvain Joyeux wrote:
it seems like you should be able to define a finalizer on any object
without preventing it from being gc'd!
The only way I am aware of is to use methods ...
ObjectSpace.define_finalizer(obj, &method(:my_finalizer))
-- Sylvain Joyeux http://www.laas.fr/~sjoyeux
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama
On Sep 25, 2007, at 10:14 AM, Sylvain Joyeux wrote:
it seems like you should be able to define a finalizer on any object
without preventing it from being gc'd!
The only way I am aware of is to use methods ...
ObjectSpace.define_finalizer(obj, &method(:my_finalizer))
-- Sylvain Joyeux http://www.laas.fr/~sjoyeux
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama
Well, I thought I already tried and that it worked fine... But I think I found
the problem ...
define_finalizer does not take any block ! (so, it is normal that it is not
called ;-)) You have to write either the thing Ilmari suggested or remove
the '&' before the method (it works, I just tried it)