Question

I'm using the latest release of the PyGTK All-in-One installer (2.24.2) for Python 2.7 which includes Cairo 1.10.8, Pango 1.29.4, PyGTK 2.24.0, and PyGobject 2.28.3 (I think).

The following code leaks ~55 MB of memory:

import gtk

window = gtk.Window()
label = gtk.Label()
window.add(label)
window.show_all()
for _ in range(100000):
    label.set_markup('Leaking memory!')
    while gtk.events_pending():
        gtk.main_iteration()

Note: The for loop is in my test script just so I could see the memory consumption increase in Task Manager. It's also essentially what's going on in my real application, except the label text changes at least once per second instead of just being redrawn with the same text each time.

The problem line is label.set_markup(), which leaks about 0.5kB per call so I suspect the problem is in GTK or Cairo somewhere. It's possibly this bug (685959), as pointed out by a commenter.

I tried using objgraph to see if any extra Python objects are showing up in proportion to the number of calls to gtk.Label.set_markup() but there are no excess objects. It follows that calls to gc.collect() don't help, and I tried it to be sure. Python doesn't seem to be aware of the objects which are responsible for the memory consumption.

How do I find this memory leak, and/or work around it? I need to use markup to style some text for this application, but I tried using gtk.Label.set_text() as a workaround and it leaks memory too.

I should note that this application targets Windows so using PyGObject to get GTK 3 is not an option -- GObject introspection is still not available on Windows.

Was it helpful?

Solution

Bug (685959) is indeed the problem. The bug is fixed in gtk+ 2.24.14. However, 2.24.14 won't compile for win32 (I hope anyone reading my question and answer realizes at this point that GTK is no longer a reasonable choice or cross-platform development).

I applied this patch to 2.24.10 and successfully compiled the result. With my new runtime files it seems to be working.

I used the instructions here to build GTK on Windows with MinGW: http://ingar.intranifty.net/devenv/mingw32/gtk.html

The 32-bit build will fail around gtk-update-icon-cache unless you run the msys shell as administrator. For the 64-bit build, you need to rm gtk/gtk.def before running make. Build and install gtk+ by executing the following commands:

cd $LOCALBUILDDIR && \ wget -c http://ftp.gnome.org/pub/gnome/sources/gtk+/2.24/gtk+-2.24.10.tar.xz && \ xz -d -c gtk+-2.24.10.tar.xz | tar xv && \ cd gtk+-2.24.10 && \ ./configure --prefix=$LOCALDESTDIR --with-gdktarget=win32 \ --with-included-immodules=ime --disable-debug --disable-gtk-doc && \ make && \ make install

I know this isn't a "workaround" like I asked for in my question, but over 6 months without an answer tells me there is no workaround except fixing the bug in the runtime...

OTHER TIPS

If you need a fixed Gtk+2 runtime for Windows you can use the Gnome Glade Gtk+ 3.8.5 for Windows which includes the fixed Gtk+ 2.24.23 runtime. http://ftp.gnome.org/pub/GNOME/binaries/win32/glade/3.8/glade-3-8-5-installer.exe

Or build latest Gtk+2 from source for Windows which is also easy using the gtk+ tutorial. https://www.gtk.org/download/windows.php

Copy the dlls to your program or add to PATH when build and install your program.

(PyGTK stays the same API version 2.24.0 it is only the link for python to the Gtk+2 runtime.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top