Small question, are the items that are not collected in the destroyed state?

Regards, Arjan
Op 23 dec. 2010 16:02 schreef "Gerald Britton" <[email protected]>
het volgende:
> We encountered this problem in our project (gramps-project.org). It
> took quite a bit of work to remove the refs to allow GC. Basically, we
> added code to track the callbacks then, when the objects were deleted,
> added code to explicitly remove them (delete them or set them to None)
> to break the cyclical refs. Also, we added code to delete (or set to
> None) attributes that might possibly be involved in the cycle.
>
> It was a lot of work but we eventually stopped the memory leaks.
> Still, I believe that pygtk could be a LOT smarter in this regard. I
> think that what we had to do amounts to fixing a serious design issue
> in pygtk.
>
> On Tue, Dec 21, 2010 at 12:16 PM, Pierre <[email protected]> wrote:
>> Hello list,
>>
>> I run into a surprising behavior regarding garbage collection. In the
>> following example, a Notebook page is removed from its parent widget and
>> destroyed. However, the page is not garbage-collected unless the "tab"
>> widget (a gtk.HBox) is first destroyed.
>>
>> Only the Page instance refers to the "tab" widget. Besides, "tab" is
>> indirectly associated to the page: one of its child widget's signal is
>> connected to a Page method. So we have something like this:
>>
>>  page --> tab --> button --> callback --> page --> tab --> etc.
>>
>> Once remove_page() returns, I would expect tab and page to be destroyed
and
>> collected, because both objects become unreachable (unreachable through
>> Python variables and GTK calls). But the gc module shows that they are
not
>> collected.
>>
>> Is this the expected behavior ?  I'm using pygtk 2.17.0, gtk 2.20.1, and
>> Python 2.6.6.
>>
>> Thank you for your time.
>>
>> Pierre
>>
>>
>> # ------------------------------------------------------ #
>>
>> import gc
>> import gtk
>> import gobject
>>
>> DESTROY_TAB = False
>>
>> class Page(gtk.VBox):
>>
>>    def __init__(self):
>>        gtk.VBox.__init__(self)
>>        self.pack_start(gtk.TextView(), True, True) # To fill the window
>>        button = gtk.Button()
>>        button.connect("clicked", self.hello)
>>        title = gtk.Label("hello")
>>        tab = gtk.HBox()
>>        tab.pack_start(title, True, True)
>>        tab.pack_end(button, False, False)
>>        tab.show_all()
>>
>>        # Keeping a reference here is the culprit. Could it be a
>>        # circular reference problem ?
>>        # tab --> button --> hello --> page --> tab --> ...
>>        self.tab = tab
>>
>>    def hello(self, widget):
>>        print "hello"
>>
>> def add_page(notebook):
>>    print "Adding a page to the Notebook."
>>    page = Page()
>>    page.show_all()
>>    notebook.append_page(page, tab_label=page.tab)
>>
>> def remove_page(notebook):
>>    print "Removing the page."
>>    page = notebook.get_nth_page(0)
>>    notebook.remove_page(0)
>>    page.destroy()
>>    # Destroying page.tab let the GC collect the page.
>>    if DESTROY_TAB:
>>        page.tab.destroy()
>>
>> def main():
>>    notebook = gtk.Notebook()
>>    w = gtk.Window()
>>    w.add(notebook)
>>    w.resize(400, 400)
>>    w.show_all()
>>    w.connect("destroy", gtk.main_quit)
>>    gobject.idle_add(add_page, notebook)
>>    gobject.timeout_add(1000, remove_page, notebook)
>>    gobject.timeout_add(2000, gtk.main_quit)
>>    gtk.main()
>>
>> def seek_page():
>>    gc.collect()
>>    oo = gc.get_objects()
>>    for o in oo:
>>        if hasattr(o, "__class__") and (o.__class__ is Page
>>                                        or o.__class__ is gtk.HBox):
>>            print
>>            print o, "escaped garbage collection"
>>            print 'Referrers are :'
>>            for r in gc.get_referrers(o):
>>                print '  *', repr(r)[:65], '...'
>>
>>
>> main()
>> seek_page()
>>
>>
>> # Output:
>> # ------
>> #
>> # Adding a page to the Notebook.
>> # Removing the page.
>> #
>> # <Page object at 0x98a898c (GtkVBox at 0x9960c18)> escaped garbage
>> collection
>> # Referrers are :
>> #   * [(), {'__setattr__': <slot wrapper '__setattr__' of 'object' obje
...
>> #   * <bound method Page.hello of <Page object at 0x98a898c (GtkVBox at
...
>> #   * <frame object at 0x999f68c> ...
>> #
>> # <gtk.HBox object at 0x98a8a04 (GtkHBox at 0x9960c70)> escaped garbage
>> collection
>> # Referrers are :
>> #   * [(), {'__setattr__': <slot wrapper '__setattr__' of 'object' obje
...
>> #   * <frame object at 0x999f68c> ...
>> #   * {'tab': <gtk.HBox object at 0x98a8a04 (GtkHBox at 0x9960c70)>} ...
>> _______________________________________________
>> pygtk mailing list   [email protected]
>> http://www.daa.com.au/mailman/listinfo/pygtk
>> Read the PyGTK FAQ: http://faq.pygtk.org/
>>
>
>
>
> --
> Gerald Britton
> _______________________________________________
> pygtk mailing list [email protected]
> http://www.daa.com.au/mailman/listinfo/pygtk
> Read the PyGTK FAQ: http://faq.pygtk.org/
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to