【问题标题】:Does pygtk garbage-collect runtime-created functions connected to signals?pygtk 垃圾收集连接到信号的运行时创建的函数吗?
【发布时间】:2014-10-31 21:46:33
【问题描述】:

我正在使用 PyGtk。

当小部件被销毁时,连接到小部件的信号“drag_data_get”的运行时生成函数是否会被垃圾收集

关于创建并与拖动源/目标目标关联的 Gtk.TargetList 的相同问题?

我确实找到了Python and GTK+: How to create garbage collector friendly objects?,但这并没有太大帮助。

【问题讨论】:

    标签: python drag-and-drop garbage-collection gtk pygtk


    【解决方案1】:

    简而言之:是的,确实如此,动态创建的函数就像在运行时创建的任何其他 Python 对象一样创建。

    更长的答案:对于由垃圾收集器管理的资源,例如未绑定到外部资源的对象,Python 和 PyGTK 将正确处理未使用的对象。对于外部资源,例如打开的文件或正在运行的线程,您需要采取措施确保正确清理它们。要准确回答您的问题,查看具体代码会很有用。一般来说,以下几点适用于 Python 和 GTK:

    • Python 对象(包括动态创建的函数)在无法从 Python 中访问后的一段时间内被释放。在某些情况下,在对象变得无法访问后立即解除分配(如果对象未参与引用循环),而在其他情况下,您必须等待垃圾收集器启动。

    • 销毁小部件会导致与小部件关联的 GTK 资源立即被清除。对象本身可以保持活动状态。可通过小部件访问的回调应立即取消引用,并且如果 Python 没有其他任何东西保留它们,则很快就会取消分配。

    您可以使用weakref 模块中的弱引用类型来测试它。例如:

    >>> import gtk
    >>> 
    >>> def report_death(obj):
    ...     # arrange for the death of OBJ to be announced
    ...     def announce(wr):
    ...         print 'gone'
    ...     import weakref
    ...     report_death.wr = weakref.ref(obj, announce)
    ... 
    >>> def make_dynamic_handler():
    ...     def handler():
    ...         pass
    ...     # for debugging - we want to know when the handler is freed
    ...     report_death(handler)
    ...     return handler
    ... 
    >>> w = gtk.Window()
    >>> w.connect('realize', make_dynamic_handler())
    10L
    >>> w.destroy()
    gone
    

    现在,如果您将代码更改为 handler 以包含循环引用,例如通过修改它来提及自己:

    def handler():
        handler      # closure with circular reference
    

    ...对destroy 的调用将不再导致立即打印gone - 这将需要程序继续工作,或显式调用gc.collect()。在大多数 Python 和 PyGTK 程序中,自动解除分配“正常工作”,您无需努力帮助它。

    最终,唯一可靠测试是否存在内存泄漏是在无限循环中运行可疑代码并监控进程的内存消耗 - 如果它无限增长,则某些东西没有得到已释放,您有内存泄漏。

    【讨论】:

    • 非常感谢您的详尽回答。我更特别关注拖放部分。由于涉及到一些用户交互,因此无限循环不容易用于测试。您的回答促使我暂时信任 PyGtk,因为这些对象(函数、TargetList)应该由垃圾收集器管理。谢谢。
    • @BastienJacquet 没问题 - 另一种测试方法是将大对象附加到函数,或使用答案中显示的report_death 函数对其进行监视。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    相关资源
    最近更新 更多