# ObjectSpace.define\_finalizer and memory leaks

**URL:** <https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484>\
**Category:** Ruby\
**Created:** [September 25, 2007, 6:03pm UTC](https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484 "2007-09-25T18:03:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [September 25, 2007, 6:03pm UTC](https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484/1 "2007-09-25T18:03:01Z")

</div>

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!

cheers.

a @ [http://drawohara.com/](http://drawohara.com/)

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [September 25, 2007, 6:14pm UTC](https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484/2 "2007-09-25T18:14:06Z")

</div>

On 9/25/07, ara.t.howard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> end
> ObjectSpace.define_finalizer(c){ :nothing }
> 
> ```
> 
> 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.

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [September 25, 2007, 6:16pm UTC](https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484/3 "2007-09-25T18:16:07Z")

</div>

> 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))

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [September 25, 2007, 6:34pm UTC](https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484/4 "2007-09-25T18:34:09Z")

</div>

On Sep 25, 2007, at 10:14 AM, Sylvain J. 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 J. [http://www.laas.fr/](http://www.laas.fr/)  
> > ~sjoyeux

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?

thanks alot for the input.

kind regards.

a @ [http://drawohara.com/](http://drawohara.com/)

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [September 25, 2007, 7:22pm UTC](https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484/5 "2007-09-25T19:22:21Z")

</div>

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)

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [September 25, 2007, 6:50pm UTC](https://www.ruby-forum.com/t/objectspace-define-finalizer-and-memory-leaks/115484/6 "2007-09-25T18:50:12Z")

</div>

On Sep 25, 2007, at 10:14 AM, Sylvain J. 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 J. [http://www.laas.fr/](http://www.laas.fr/)  
> > ~sjoyeux

working off of you idea of avoiding any new references whatsoever i  
came up with this, which is working for me, can others confirm?

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 finalizer\_for object\_id  
lambda { p [:finalized, object\_id] if $DEBUG }  
end

loop do  
(2 \*\* 16).times do  
c = C.new  
finalizer = finalizer\_for c.object\_id  
c.instance\_eval do  
ObjectSpace.define\_finalizer self, &finalizer  
end  
end

puts “before: #{ C.count }”

GC.start

puts “after: #{ C.count }”  
puts  
end

thanks for the inspiration!

kind regards.

a @ [http://drawohara.com/](http://drawohara.com/)
