【问题标题】:Removing tkinter frame without memory leak在没有内存泄漏的情况下删除 tkinter 帧
【发布时间】:2021-12-19 23:28:58
【问题描述】:

在销毁第一个子帧并初始化第二个帧后,父对象仍保留一些关于第一个子帧存在的记忆,如.!frame2 中的2 所示。

我的问题是,

  • 如果子对象已被销毁,该对象如何跟踪其过去的子对象?

  • 是否有最佳实践或其他一些程序来扭转/保持这一点?

虽然下面的示例代码很简单,但我的实际应用程序涉及销毁和创建数百个子帧,我注意到当打包许多帧时它会变慢。

代码

import tkinter

x = tk.Tk()
tk.Frame(x)
x.winfo_children()[0].destroy()
tk.Frame(x)
print(x.winfo_children())

输出

[<tkinter.Frame object .!frame2>]

【问题讨论】:

  • 而且我注意到当很多帧被打包时它会变慢。如果你将数百个帧打包到你的窗口中,那么我猜你误解了一些东西,只要你没有墙那么大的显示器,好像没这个必要。

标签: python tkinter memory


【解决方案1】:

如果子对象已被销毁,该对象如何跟踪其过去的子对象?

它只是一个简单的字典,为每个小部件类型、每个主小部件维护一个计数器。这是更新计数器的代码的 sn-p(来自 tkinter/__init__.py):

class BaseWidget(Misc):
    ...    
    def _setup(self, master, cnf):
        ...
        if not name:
            name = self.__class__.__name__.lower()
            if master._last_child_ids is None:
                master._last_child_ids = {}
            count = master._last_child_ids.get(name, 0) + 1
            master._last_child_ids[name] = count
            if count == 1:
                name = '!%s' % (name,)
            else:
                name = '!%s%d' % (name, count)

是否有最佳实践或其他一些程序来扭转/保持这一点?

最好的做法是不要担心。每个小部件的计数器只占用几个字节。

如果为您创建的每个小部件设置name 属性,则可以避免创建计数器。根据您的小部件的组织方式,这可能只会为您节省几千字节的内存。

可以想象,一个深度嵌套的层次结构可以达到数十或数百千字节,但如果 tkinter 因其他原因而失败,则很难达到一个兆字节。

【讨论】:

    猜你喜欢
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 2021-12-02
    • 1970-01-01
    相关资源
    最近更新 更多