Memory Leaks … Finally gone?
Everyone using Gramps for an extended period of time will have noticed the huge memory footprint Gramps takes up after a while. This is a consequence of using GTK from python, with orphaned objects the garbage collector is unable to collect. So a very technical issue. Using glade is specifically troublesome, as it is unclear why some things cause memory leaks and others not.
However, there are easy ways to help the garbage collector in its work: remove self links to methods, delete object attributes holding glade GTK objects, clear dictionaries and lists holding pointers to methods or objects.
Problem is only you need a well defined place to store these garbage collection aids, specifically, a method you know will be called. Such a place has now been added. Models now have a destroy method where the model can be prepared for garbage collection. Everytime a view/selector/tab creates a new model (eg after running a filter), the previous model must be destroyed in this way.
Likewise, we already had _cleanup_db_connects method on GUI elements, this now has been joined with a _cleanup_local_connects and a _cleanup_on_exit method. The connect cleanup methods remove callback connects to GUI, while the last method was already present on some elements in 3.2.4 and has now been extended to more objects, like the displaytabs in editors. The _cleanup_on_exit method is called after the GTK window has been destroyed, and must hence finalize any other links that hinder garbage collection.
The typical ending sequence of an element is hence:
def close(self): self._cleanup_db_connects() self._cleanup_connects() ManagedWindow.close(self) self._cleanup_on_exit() #now do callback if needed to the caller of this window self.caller_callback_on_close
In the above, _cleanup_connects calls the _cleanup_local_connects, and the ManagedWindow.close calls destroy on the GTK top window, as well as deleting GUI references which have been marked via the track_ref_for_deletion method defined in the ManagedWindow class.
These changes will land in 3.2.5, with further improvements in future 3.3. Let’s hope it makes for happier users.
Benny
Eero Tamminen
5 March 2011 @ 9:21 pm
One thing that’s easy to miss with Gtk/Gobject is that Gobject deletes signals/connections between objects only when both objects go away. If you have temporary objects that are connected to a long term object that doesn’t go away, you need to track the connections and delete them manually, otherwise you’ll leak them. At least that was the case few years ago…
(I think Qt deletes them already when one of the objects goes away.)