重绘标签时,解决GTK中的大内存泄漏问题

时间:2013-05-03 20:14:00

标签: python gtk pygtk pango

我正在使用最新版本的PyGTK All-in-One安装程序(2.24.2)用于Python 2.7,其中包括Cairo 1.10.8,Pango 1.29.4,PyGTK 2.24.0和PyGobject 2.28.3(我想)。

以下代码泄漏~55 MB内存:

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()

注意:for循环在我的测试脚本中,所以我可以看到任务管理器中的内存消耗增加。它本质上也是我真实应用程序中发生的事情,除了标签文本每秒至少更改一次,而不是每次都重写相同的文本。

问题行是label.set_markup(),每次调用泄漏大约0.5kB,所以我怀疑问题出在GTK或Cairo的某个地方。正如评论者指出的那样,它可能是this bug (685959)

我尝试使用objgraph来查看是否有任何额外的Python对象与gtk.Label.set_markup()的调用次数成比例,但是没有多余的对象。因此,对gc.collect()的调用没有帮助,我试着确定。 Python似乎并不知道负责内存消耗的对象。

如何找到此内存泄漏,和/或解决它?我需要使用标记来为这个应用程序设置一些文本样式,但我尝试使用gtk.Label.set_text()作为解决方法,它也会泄漏内存。

我应该注意到这个应用程序是针对Windows的,所以使用PyGObject来获取GTK 3不是一个选项 - GObject内省仍然在Windows上不可用。

2 个答案:

答案 0 :(得分:3)

Bug (685959)确实是问题所在。该错误在gtk + 2.24.14中修复。但是,2.24.14不会为win32编译(我希望有人在阅读我的问题和答案时意识到GTK不再是一个合理的选择或跨平台开发)。

我将this patch应用于2.24.10并成功编译了结果。使用我的新运行时文件,它似乎正在运行。

我使用这里的说明在MinGW的Windows上构建GTK: http://ingar.intranifty.net/devenv/mingw32/gtk.html

  

除非你运行,否则32位构建将在gtk-update-icon-cache周围失败   msys shell作为管理员。对于64位版本,您需要rm   gtk / gtk.def在运行make之前。通过执行构建和安装gtk +   以下命令:

     

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 |焦油xv&& \ cd gtk + -2.24.10&& \   ./configure --prefix = $ LOCALDESTDIR --with-gdktarget = win32 \   --with-included-immodules = ime --disable-debug --disable-gtk-doc&& \ make&& \ make install

我知道这不是我在问题中提出的“解决方法”,但超过6个月没有回答告诉我除了在运行时修复错误之外没有其他解决办法......

答案 1 :(得分:1)

如果你需要一个固定的Gtk + 2运行时Windows,你可以使用Gnome Glade Gtk + 3.8.5 for Windows,其中包括固定的Gtk + 2.24.23运行时。 https://github.com/PimDeWitte/UnityMainThreadDispatcher/blob/master/UnityMainThreadDispatcher.cs

或者从Windows源代码构建最新的Gtk + 2,使用gtk +教程也很容易。 http://ftp.gnome.org/pub/GNOME/binaries/win32/glade/3.8/glade-3-8-5-installer.exe

将dll复制到您的程序或在构建和安装程序时添加到PATH。

(PyGTK保持相同的API版本2.24.0,它只是python到Gtk + 2运行时的链接。)