Bug #6614
closedGC doesn't collect objects bound to (collectable) proc
Description
Hello all.
Previously discussed here: http://www.ruby-forum.com/topic/4402823
I would expect the following code to eventually run the finalizers mentioned:
def finalized_puts bad
ObjectSpace.define_finalizer(bad) { print 'collector run', bad }
end
loop { finalized_puts [] }
This works in jruby as expected, but not in MRI. This has the unfortunate side effect of making define_finalizer very difficult to actually use right http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
Cheers!
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
- Status changed from Open to Rejected
=begin
Finalizers will run ((AFTER)) the target object has been destroyed and collected, so finalizers ((MUST NOT)) refer the object.
I'm not certain why it is called in JRuby, but suspect it might be optimized out?
=end
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
=begin
A correction.
Your code uses (({print})) but not (({printf})), so the arguments cannot be optimized out, even if necessary assumptions are all met.
A possibility would be JRuby calls finalizers ((BEFORE)) the destruction.
What's printed in JRuby?
=end
Updated by Anonymous over 12 years ago
Your code uses
print' but not
printf', so the arguments cannot be optimized out, even if necessary assumptions are all met.
A possibility would be JRuby calls finalizers BEFORE the destruction.
What's printed in JRuby?
runcollector runcollector
so it still has a reference to the old object. Which way seems more
sane somehow, but is probably wrong.
I suppose my gripe is more that define_finalizer too many times
creates proc's that are essentially "orphaned" but cannot be
collected, which is basically a memory leak waiting to happen.
Cheers!
-r
Updated by headius (Charles Nutter) over 12 years ago
Finalizers in JRuby are stored on a reference from the object itself, so they don't actually prevent the object from collecting.
I'd vote for MRI to do the same, but I don't think I'll win that fight :)
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
headius (Charles Nutter) wrote:
Finalizers in JRuby are stored on a reference from the object itself, so they don't actually prevent the object from collecting.
You're missing the point.
Updated by cjheath (Clifford Heath) over 12 years ago
On 27/06/2012, at 4:35 PM, nobu (Nobuyoshi Nakada) wrote:
headius (Charles Nutter) wrote:
Finalizers in JRuby are stored on a reference from the object itself, so they don't actually prevent the object from collecting.
You're missing the point.
Is he? Surely somewhere in that loop{finalized_puts []} the GC will activate,
and that will find collectable objects (with finalisers attached in JRuby). In
MRI, they might be found but they won't be finalised, if I understand the
behaviour right.
Clifford Heath.
Bug #6614: GC doesn't collect objects bound to (collectable) proc
https://bugs.ruby-lang.org/issues/6614#change-27513Author: rogerdpack (Roger Pack)
Status: Rejected
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: tcs-ruby 1.9.3p28 (2012-01-28, TCS patched 2012-01-30) [i386-mingw32]Hello all.
Previously discussed here: http://www.ruby-forum.com/topic/4402823I would expect the following code to eventually run the finalizers mentioned:
def finalized_puts bad
ObjectSpace.define_finalizer(bad) { print 'collector run', bad }
endloop { finalized_puts [] }
This works in jruby as expected, but not in MRI. This has the unfortunate side effect of making define_finalizer very difficult to actually use right http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
Cheers!
Updated by shyouhei (Shyouhei Urabe) over 12 years ago
cjheath (Clifford Heath) wrote:
On 27/06/2012, at 4:35 PM, nobu (Nobuyoshi Nakada) wrote:
headius (Charles Nutter) wrote:
Finalizers in JRuby are stored on a reference from the object itself, so they don't actually prevent the object from collecting.
You're missing the point.
Is he? Surely somewhere in that loop{finalized_puts []} the GC will activate,
and that will find collectable objects (with finalisers attached in JRuby). In
MRI, they might be found but they won't be finalised, if I understand the
behaviour right.
When a proc that touches an object is attatched to that object's finalizer, that finalizer can "escape" that object.
ObjectSpace.define_finalizer(obj) { $escaped = obj } # Woo!
This would break the whole concept of finalizing. Nobu's point is that how JRuby prevents this situation.
Updated by funny_falcon (Yura Sokolov) over 12 years ago
It seems that ObjectSpace.define_finalizer is complitely broken with Ruby 1.9.3
And even in Ruby 1.8.7 finalizer proc ought to be created in other scope to not hold reference to object in its binding.
See #6664 and https://gist.github.com/3009867 for more