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/
