Observers not garbage collected?
-
Create an observer class...
class ObTest < Sketchup::ModelObserver; def onTransactionUndo(model); puts 'onTransactionUndo'; end; end; nil model=Sketchup.active_model #<Sketchup::Model:0xf584d10>
Create an model observer and test it...
x = ObTest.new #<ObTest:0xf4f5568> model.add_observer( x ) true onTransactionUndo onTransactionUndo onTransactionUndo
Check the instance count for the observer...
ObjectSpace.each_object(ObTest){} 1
As expected.Remove the observer...
model.remove_observer( x ) true ObjectSpace.each_object(ObTest){} 1
Still one - but we have not triggered the GC yet.Trigger the GC...
GC.start nil ObjectSpace.each_object(ObTest){} 1
Still there! This is not expected.Set our instance reference to
nil
...
x=nil nil GC.start nil ObjectSpace.each_object(ObTest){} 1
Still there!!Any ideas?
Bug? -
Yes a bug in a way... the call to add_observer creates a C++ reference to the object that is not released by the remove_observer call.
So ..Ruby GC cannot dispose of the object.
In the test code below, you'll see the object is GC'd when the add_observer and remove_observer calls are commented out. -
This is somewhat troublesome.
One would then have to be very careful when creating observer instances. Ideally only create one instance - ever, if possible.
And also clean up any references the observer has to other objects when possible, as otherwise they won't be GC'd either.grumble refactoring time.
Advertisement