лук-порей с памятью tkinter Treeview

#python-3.x #tkinter #memory #memory-leaks #tcl

Вопрос:

Это мой код:

 from tkinter import ttk
from tkinter import Tk, Button

def destroy_root():
    global tree, root
    # tree.delete(*tree.get_children()) # Doesn't help, actually increases memory usage
    tree.destroy()
    root.destroy()
    del tree
    del root

root = Tk()

Button(root, text="Destroy root", command=destroy_root).pack()

tree = ttk.Treeview(root)
tree.pack()
tree["columns"] = ["0"]

for i in range(1000000):
    tree.insert("", "end", i, values=(i, ))

root.mainloop()
 

Когда я запускаю проблему, она использует 452 МБ оперативной памяти:

452 МБ оперативной памяти

Когда я нажимаю "Destroy root" кнопку, он по-прежнему использует 444 МБ оперативной памяти:

введите описание изображения здесь

Это почему? Не должно ли использование памяти сократиться до менее чем 100 МБ?

Кроме того, если я удалю элементы внутри treeview перед его уничтожением, использование памяти увеличится до более чем 600 МБ:

659 МБ оперативной памяти

Означает ли это, что где-то внутри /есть утечка памяти tkinter tcl ?

Комментарии:

1. Похоже, это что-то о оболочке Python. Если вы запустите скрипт через cmd ( python file.py ) или дважды щелкнув файл, то после нажатия кнопки этот процесс исчезнет. Если вы откроете и запустите файл через Python IDLE, этот процесс останется в диспетчере задач до тех пор, пока вы не закроете окно оболочки Python. Если вы добавите exit() после root.mainloop() , то после нажатия кнопки появится сообщение оболочки (ваша программа все еще запущена! Ты хочешь его убить?).

2. То же самое для других скриптов Python (не tkinter), два процесса для pythonw.exe. Также интересно, как это работает.

3. Необязательно. Это может быть просто распределитель памяти с высокой отметкой. (Когда выделено много небольшой памяти, определить, когда возвращать память в ОС, действительно довольно сложно.) Убедитесь, что в вашей операционной системе достаточно места для расширения файла подкачки.

4. Но я могу подтвердить, что уничтожение виджета любым механизмом, который вы можете придумать , всегда должно должным образом уничтожать и его потомков.

5. @8349697 Добавьте input(">>> ") в конец кода и запустите его с помощью любого cmd/двойного щелчка