2

I have a custom gtk.treeview wrapper class that manages its own liststore. The class has its own method that clears the liststore's data and overwrites it with new data. For the purpose of testing memory consumption,the treeview just displays 50,000 rows of integers in 8 columns.

I've noticed that every call to my function that updates the liststore with data seems to increase the memory the application uses, and it never goes back down after data is cleared.

Here is my simple treeview implementation:

class TreeViewPrototype(gtk.TreeView):
    def __init__(self):
        gtk.TreeView.__init__(self)

        self.columns = [str, str, str, str, str, str, str, str]
        # Initialize Treeview  and TreeViewColumns here
        # Setup columns
        self.liststore = gtk.ListStore(*self.columns)
        self.set_model(self.liststore)

    def set_list_model(self):
        self.liststore.clear()
        self.liststore = gtk.ListStore(*self.columns)
        # Populate liststore with dummy data
        for i in range(50000):
            row = []
            for j in range(len(self.columns)):
                row.append("%d[%d]"%(i,j))
            self.liststore.append(row)

It seems to me that every call to set_list_model, when I overwrite the liststore with a new one, it never unallocates the memory of the data. What am I doing wrong?

gpoo
  • 8,408
  • 3
  • 38
  • 53
Wes
  • 954
  • 13
  • 25
  • how do you set the list store as the data store of the tree view? – XORcist Feb 16 '12 at 20:14
  • @möter Sorry, I unintentionally left it out. Edited to fix that. – Wes Feb 16 '12 at 21:07
  • you do not seem to re-set the data store to the new ListStore instance in set_list_model. – XORcist Feb 16 '12 at 21:35
  • @möter The ListStore is being updated with the new data, but the old data still takes up memory – Wes Feb 16 '12 at 21:43
  • the data is not being updated. all you do is create ListStore instances that are never displayed in the tree view and fillingthem with new data. if you do this a lot of times, the PC may be too busy creating the useless list stores, so that garbage collection has no chance to kick in. – XORcist Feb 16 '12 at 21:56
  • @möter `self.liststore.clear()` according to [here](http://www.pygtk.org/docs/pygtk/class-gtkliststore.html#method-gtkliststore--clear) removes all liststore rows. Does this mean the data will just sit there in memory then? – Wes Feb 16 '12 at 22:10
  • I guess not. but if you are generating 400.000 string objects at every call and calls are repeated quickly, maybe it's a performance issue with the PC. But I'm speculating, I don't have an answer. Maybe try a memory profiler. – XORcist Feb 16 '12 at 22:16

1 Answers1

3

The problem seems to be with the reference to the liststore in the treeview. Because the treeview is a container that is present throughout the entire lifecycle of the application, the old liststore hangs around, being still referenced by the treeview's constructor. If a new liststore is created everytime and no reference is held by the treeview, that problem seems to go away.

My Solution:

class TreeViewPrototype( gtk.TreeView ):
   def __init__(self):
       gtk.TreeView.__init__(self)
       self.columns = [str,str,str,str,str,str,str,str]
       #TreeView Initialization

   def set_list_model( self ):
       self.set_model(None)
       liststore = gtk.ListStore( *self.columns)
       for i in range( 50000 ):
           row = []
           for j in range( len( self.columns)):
               row.append( "%d[%d]"%(i,j))
           liststore.append( row )
       self.set_model( liststore )

Using set_model(None) seems to correctly dereference the current liststore in the model so it doesn't hang around in memory.

Wes
  • 954
  • 13
  • 25