【问题标题】:Working around a big memory leak in GTK when redrawing a label重绘标签时解决 GTK 中的大内存泄漏问题
【发布时间】:2013-05-03 20:13:59
【问题描述】:

我正在为 Python 2.7 使用最新版本的 PyGTK All-in-One 安装程序 (2.24.2),其中包括 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 或开罗的某个地方。正如评论者指出的那样,它可能是this bug (685959)

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

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

我应该注意这个应用程序以 Windows 为目标,因此使用 PyGObject 来获取 GTK 3 不是一种选择 -- GObject 内省仍然在 Windows 上不可用。

【问题讨论】:

  • 缩进正确吗?只要每次设置标签后都有事件,您就一直在运行 gtk.main_iteration()?
  • 是的,这是正确的做法。这基本上把主循环翻过来了。
  • @Series8217 我明白了。我刚刚在 Linux/GTK 2 上尝试过,在无限循环中,内存在一段时间后从 19.8MB 变为 20.1MB 并保持在那里。只是我的 2 美分,我无能为力了 :)
  • GTK 中存在特定于 Windows 的泄漏,最近才得到修复。例如,查看this bugthis one。您可能需要重建 GTK。
  • @user4815162342 看起来可能是 685959。不幸的是,似乎已经有一段时间没有人发布与我的环境兼容的版本了。

标签: python gtk pygtk pango


【解决方案1】:

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

我将this patch 应用到 2.24.10 并成功编译结果。使用我的新运行时文件,它似乎可以正常工作。

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

除非您运行 gtk-update-icon-cache,否则 32 位构建将失败 msys shell 作为管理员。对于 64 位版本,您需要 rm 运行 make 之前的 gtk/gtk.def。通过执行构建和安装 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 个月没有答案告诉我除了修复运行时中的错误之外没有其他解决方法...

【讨论】:

    【解决方案2】:

    如果您需要 Windows 的固定 Gtk+2 运行时,您可以使用 Gnome Glade Gtk+ 3.8.5 for Windows,其中包括固定的 Gtk+ 2.24.23 运行时。 http://ftp.gnome.org/pub/GNOME/binaries/win32/glade/3.8/glade-3-8-5-installer.exe

    或者从源代码为 Windows 构建最新的 Gtk+2,这也很容易使用 gtk+ 教程。 https://www.gtk.org/download/windows.php

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-19
      • 2010-12-11
      • 2012-05-23
      • 2011-05-25
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多