Trace what prevents an object from being GC'd?
-
@dan rathbun said:
Did you dispose of all Locals, Constants, instance vars, and perhaps maybe even Procs that are within your subclass?
I set all local variables to nil, nothing to the constants - just strings.
-
@thomthom said:
You could test the GC of a WebDialog if you like - so we can compare results. ... Confirm?
OK, here:
dlg = UI;;WebDialog.new >> #<UI;;WebDialog;0x61dc79c> ObjectSpace.each_object(UI;;WebDialog) {} >> 2 dlg=nil >> nil ObjectSpace.each_object(UI;;WebDialog) {} >> 2 GC.start >> nil ObjectSpace.each_object(UI;;WebDialog) {} >> 0 MyDialog = Class.new(UI;;WebDialog) >> MyDialog MyDialog.superclass >> UI;;WebDialog dlg=MyDialog.new >> #<MyDialog;0x6071ed4> ObjectSpace.each_object(UI;;WebDialog) {} >> 2 ObjectSpace.each_object(MyDialog) {} >> 2 dlg=nil >> nil ObjectSpace.each_object(MyDialog) {} >> 2 ObjectSpace.each_object(UI;;WebDialog) {} >> 2 GC.start >> nil ObjectSpace.each_object(MyDialog) {} >> 0 ObjectSpace.each_object(UI;;WebDialog) {} >> 0
-
But I did not
show()
the dialog in the previous test, so:dlg=MyDialog.new('Test') >> #<MyDialog;0x61d2f30> dlg.show >> true # empty dialog with title 'Test' is displayed, # .. and I close it manually. ObjectSpace.each_object(UI;;WebDialog) {} >> 2 ObjectSpace.each_object(MyDialog) {} >> 2 dlg=nil >> nil ObjectSpace.each_object(MyDialog) {} >> 2 ObjectSpace.each_object(UI;;WebDialog) {} >> 2 GC.start >> nil ObjectSpace.each_object(UI;;WebDialog) {} >> 0 ObjectSpace.each_object(MyDialog) {} >> 0
-
Are you testing on PC (v1.8.6-p287) or Mac (v1.8.5-p0) ??
I guess I should say that I'm running:
RUBY_VERSION 1.8.7 RUBY_PATCHLEVEL 299
.. get I set it for a test and forgot to set it back.
-
@ThomThom...
look at this example:
https://gist.github.com/355820A the bottom he determines that there is a finalizer that is holding a ref to the instance, and therefor the reason why the instance is not getting GC'd.
I know you were trying to use a finalizer to cleanup a temp file.. likely that's the culprit.
-
@dan rathbun said:
@ThomThom...
look at this example:
https://gist.github.com/355820A the bottom he determines that there is a finalizer that is holding a ref to the instance, and therefor the reason why the instance is not getting GC'd.
I know you were trying to use a finalizer to cleanup a temp file.. likely that's the culprit.
Not in this case. I'm testing on SU8, default Ruby. I've used finalizer, but it only triggers under OSX. And I've read the gotchas about finalizers not GC'ing - and implemented it so it doesn't hold a reference.
However, I think I'm somehow creating a reference somewhere... I just can't track it down...
-
It seems to be due to using
self.add_action_callback
within theinitialize
method of the subclass.<span class="syntaxdefault">class WC </span><span class="syntaxkeyword"><</span><span class="syntaxdefault"> UI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">WebDialog</span><span class="syntaxkeyword">;</span><span class="syntaxdefault"> def initialize</span><span class="syntaxkeyword">(*</span><span class="syntaxdefault">args</span><span class="syntaxkeyword">);</span><span class="syntaxdefault"> super</span><span class="syntaxkeyword">;</span><span class="syntaxdefault"> self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_action_callback</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'test'</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">diag</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">param</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> puts diag</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> param </span><span class="syntaxkeyword">};</span><span class="syntaxdefault">end</span><span class="syntaxkeyword">;</span><span class="syntaxdefault">end</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">nil<br /><br />ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">WC</span><span class="syntaxkeyword">){}<br /></span><span class="syntaxdefault">0<br /><br />x</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">WC</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">new </span><span class="syntaxstring">'test'<br /></span><span class="syntaxcomment">#<WC;0x18dc1000><br /><br /></span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">WC</span><span class="syntaxkeyword">){}<br /></span><span class="syntaxdefault">2<br /><br />x</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">nil<br />nil<br /><br />GC</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start<br />nil<br /><br />ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">WC</span><span class="syntaxkeyword">){}<br /></span><span class="syntaxdefault">2<br /></span>
When I use
add_action_callback
outsideinitialize
it does get GC'd.<span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">WebDialog</span><span class="syntaxkeyword">){}<br /></span><span class="syntaxdefault">2<br /><br />wd</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">WebDialog</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">new </span><span class="syntaxstring">'test'<br /></span><span class="syntaxcomment">#<UI;;WebDialog;0x18f1a2a8><br /><br /></span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">WebDialog</span><span class="syntaxkeyword">){}<br /></span><span class="syntaxdefault">4<br /><br />wd</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_action_callback</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'test'</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">diag</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">param</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> puts diag</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> param </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">true<br /><br />wd </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> nil<br />nil<br /><br />GC</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start<br />nil<br /><br />ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">WebDialog</span><span class="syntaxkeyword">){}<br /></span><span class="syntaxdefault">2<br /></span>
I don't understand why...
-
@thomthom said:
It seems to be due to using
self.add_action_callback
within theinitialize
method of the subclass.I don't understand why...
Oh.. that's an easy one: Because
**self**
IS a reference to THE instance.
So YOUR telling Ruby to keep 'literal' reference within the code.You dont need that reference by the way.. because the
initialize
method ALWAYS gets executed WITHIN the newly created instance, just after the class constructor (usuallynew
,) creates it.So just remove the "
self.
" from in front of ALL instance method calls made from within ANY of the object's instance methods. -
Interesting,
-
I had a suspicion that might be it, and it's what I had planned to try next. But I still don't understand why. As
self.add_action_callback
is just calling a method, never is self being stored in any reference... -
Removing
self.
fromadd_action_callback
made no difference. -
I finally nailed it. I created the procs for
add_action_callback
as class constants instead of creating blocks within theinitialize
method and that allowed the WebDialog to be GC'd. -
@unknownuser said:
(http://forums.sketchucation.com/viewtopic.php?f) of this topic":25oe0j3o]
Did you dispose of all Locals, Constants, instance vars, and perhaps maybe even Procs that are within your subclass?
That said... you should be able to have proc refs, if they are instance
@refs
because they are likely to have refs inside them that ref instance objects.If the class is a singleton (most WebDialogs are,) just limit the number of instances to 1, in the wrapping namespace, the same way you would for a tool instance.
Advertisement