• Login
sketchucation logo sketchucation
  • Login
πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

Trace what prevents an object from being GC'd?

Scheduled Pinned Locked Moved Developers' Forum
22 Posts 4 Posters 883 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    thomthom
    last edited by 16 Sept 2011, 13:22

    Is there a way to trace back the references of an object in some manner? Finding the cause to why an object isn't garbage collected.

    I've used ObjectSpace to inspect the count, where I've noticed some objects aren't GC'd. And after trying to set all references I know of to nil - they still aren't GC'd.

    Thomas Thomassen β€” SketchUp Monkey & Coding addict
    List of my plugins and link to the CookieWare fund

    1 Reply Last reply Reply Quote 0
    • T Offline
      tbd
      last edited by 16 Sept 2011, 15:04

      several solutions:

      • patch ruby vm - https://gist.github.com/73674
      • memproof gem - http://timetobleed.com/memprof-a-ruby-level-memory-profiler/ (Linux x64 only)
      • ripping the internals via debugger πŸ˜‰ - http://www.coffeepowered.net/2010/08/23/debugging-memory-leaks-in-ruby-with-gdb-round-2/

      does it eat a lot memory ?

      SketchUp Ruby Consultant | Podium 1.x developer
      http://plugins.ro

      1 Reply Last reply Reply Quote 0
      • T Offline
        thomthom
        last edited by 16 Sept 2011, 15:08

        @unknownuser said:

        does it eat a lot memory ?

        theee... I don't have an overview of that. ...I know... don't optimize what doesn't need to be, but it bothers me that I don't know why.

        It's a subclasses WebDialog, where a WebDialog will normally GC, my subclassed version doesn't. So everytime I create one, it lingers about. (how much memory usage, I'd expect depends on the HTML content.)

        (another odd thing about WebDialogs, when I create one, a normal one, ObjectSpace's count increased by two... πŸ˜•

        Thomas Thomassen β€” SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • D Offline
          Dan Rathbun
          last edited by 16 Sept 2011, 16:21

          @thomthom said:

          (another odd thing about WebDialogs, when I create one, a normal one, ObjectSpace's count increased by two... πŸ˜•

          I remember AdamB posting about this in another thread last year (or so,)....

          .. anyway. The "hidden" reference is held by the C++ as the object is a MFC window object (on PC,) and in ObjectiveC (on Mac,) as an NSWindow object.

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • D Offline
            Dan Rathbun
            last edited by 16 Sept 2011, 16:51

            It does occur to me that we do not have a call to tell the Sketchup C++ engine that we are done with a WebDialog instance and want it "disposed of".

            We would need an .dispose() instance method for the UI::WebDialog class, that would tell the C++ engine to get rid of it's reference (and then sets the receiver on the Ruby-side to nil [if that's possible.])

            Then you can get rid of your class definition using remove_const(:MyWebDialogSubclass)

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • T Offline
              thomthom
              last edited by 16 Sept 2011, 17:29

              The thing is, a normal WebDialog instance will be GC'd if you clear all references to it.

              But there is something I have done in my subclass that prevents this - and I'm not finding out why.. 😞

              Thomas Thomassen β€” SketchUp Monkey & Coding addict
              List of my plugins and link to the CookieWare fund

              1 Reply Last reply Reply Quote 0
              • D Offline
                Dan Rathbun
                last edited by 16 Sept 2011, 17:34

                @thomthom said:

                The thing is, a normal WebDialog instance will be GC'd if you clear all references to it.

                Sure.. as I remember Adam's post .. I thot he showed they were not GC'd.. but is was awhile back.

                It could be nothing more exotic than that Google did not account for us subclassing UI::WebDialog, similar to the way some API methods only accept exact classes and not any subclasses.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • D Offline
                  Dan Rathbun
                  last edited by 16 Sept 2011, 17:36

                  Did you dispose of all Locals, Constants, instance vars, and perhaps maybe even Procs that are within your subclass?

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    thomthom
                    last edited by 16 Sept 2011, 17:37

                    Maybe... I was planning on trying a simple subclass - without all the stuff I have in mine. Just to see if that makes the differences.

                    You could test the GC of a WebDialog if you like - so we can compare results.

                    I did a count of the existing WebDialogs, then created a new one. Made a new count ( +2 in my results ) then I set my references to the WD to nil and invoke GC.start. The count then went down by 2. Confirm?

                    Thomas Thomassen β€” SketchUp Monkey & Coding addict
                    List of my plugins and link to the CookieWare fund

                    1 Reply Last reply Reply Quote 0
                    • T Offline
                      thomthom
                      last edited by 16 Sept 2011, 17:38

                      @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.

                      Thomas Thomassen β€” SketchUp Monkey & Coding addict
                      List of my plugins and link to the CookieWare fund

                      1 Reply Last reply Reply Quote 0
                      • D Offline
                        Dan Rathbun
                        last edited by 16 Sept 2011, 18:41

                        @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
                        
                        

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          Dan Rathbun
                          last edited by 16 Sept 2011, 18:44

                          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
                          

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • D Offline
                            Dan Rathbun
                            last edited by 16 Sept 2011, 18:50

                            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.

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • D Offline
                              Dan Rathbun
                              last edited by 16 Sept 2011, 22:34

                              @ThomThom...

                              look at this example:
                              https://gist.github.com/355820

                              A 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.

                              I'm not here much anymore.

                              1 Reply Last reply Reply Quote 0
                              • T Offline
                                thomthom
                                last edited by 16 Sept 2011, 22:59

                                @dan rathbun said:

                                @ThomThom...

                                look at this example:
                                https://gist.github.com/355820

                                A 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...

                                Thomas Thomassen β€” SketchUp Monkey & Coding addict
                                List of my plugins and link to the CookieWare fund

                                1 Reply Last reply Reply Quote 0
                                • T Offline
                                  thomthom
                                  last edited by 17 Sept 2011, 16:43

                                  It seems to be due to using self.add_action_callback within the initialize 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 outside initialize 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...

                                  Thomas Thomassen β€” SketchUp Monkey & Coding addict
                                  List of my plugins and link to the CookieWare fund

                                  1 Reply Last reply Reply Quote 0
                                  • D Offline
                                    Dan Rathbun
                                    last edited by 17 Sept 2011, 22:18

                                    @thomthom said:

                                    It seems to be due to using self.add_action_callback within the initialize 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 (usually new,) 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.

                                    I'm not here much anymore.

                                    1 Reply Last reply Reply Quote 0
                                    • Chris FullmerC Offline
                                      Chris Fullmer
                                      last edited by 17 Sept 2011, 22:33

                                      Interesting, πŸ‘

                                      Lately you've been tan, suspicious for the winter.
                                      All my Plugins I've written

                                      1 Reply Last reply Reply Quote 0
                                      • T Offline
                                        thomthom
                                        last edited by 17 Sept 2011, 23:31

                                        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... ❓

                                        Thomas Thomassen β€” SketchUp Monkey & Coding addict
                                        List of my plugins and link to the CookieWare fund

                                        1 Reply Last reply Reply Quote 0
                                        • T Offline
                                          thomthom
                                          last edited by 17 Sept 2011, 23:36

                                          Removing self. from add_action_callback made no difference.

                                          Thomas Thomassen β€” SketchUp Monkey & Coding addict
                                          List of my plugins and link to the CookieWare fund

                                          1 Reply Last reply Reply Quote 0
                                          • 1
                                          • 2
                                          • 1 / 2
                                          1 / 2
                                          • First post
                                            3/22
                                            Last post
                                          Buy SketchPlus
                                          Buy SUbD
                                          Buy WrapR
                                          Buy eBook
                                          Buy Modelur
                                          Buy Vertex Tools
                                          Buy SketchCuisine
                                          Buy FormFonts

                                          Advertisement