Найти - Пользователи
Полная версия: canvas + image deleting = memory leak?
Начало » GUI » canvas + image deleting = memory leak?
1
WoMax
Привет,
создадим канвас и кнопку:
import tkinter as tk
class CanvasMain(tk.Frame):
    photos = {}
    id = {}
    def __init__(self, root=None):
        super(CanvasMain, self).__init__()
        self.canvas = tk.Canvas(width=500, height=500, bg='#aa9d93', bd=2, relief="solid")
        self.canvas.pack()
        self.button = tk.Button(text='Create pic', cursor = 'hand2', bd = 4, bg = 'grey', fg='white', relief='raised', font=('Comic Sans MS', 12, 'bold'), command=self.make_pic)
        self.button.pack(fill='x')
        
    def make_pic(self):
        self.photos['pic'] = tk.PhotoImage(file = 'numbers\\PythonPowered.gif')
        self.id['id_pic'] = self.canvas.create_image(12, 12, image = self.photos['pic'], anchor = 'nw')
        self.button.config(text='Delete picture', command=self.del_pic)
        print(self.canvas.find_all())
        
    def del_pic(self):       
        self.canvas.delete(self.id['id_pic'])
        self.photos.pop('pic')
        self.id.pop('id_pic')
        self.button.config(text='Create pic', command=self.make_pic)
        print(self.canvas.find_all())
        
if __name__ == '__main__':
    CanvasMain()
    tk.mainloop()

При нажатии кнопки, в канвасе создается изображение (.gif). При повторном нажатии — удаляется.
Как видно из кода, удаляется сам объект по идентификатору, а также удаляется фотка из словаря self.photos.

Для проверки смотрим вывод кол-ва объектов канваса в stdout – постоянно либо один объект, либо ноль.

То есть можем заключить, что при каждом нажатии мы создаем фотку и объект, а при повторном удаляем все, что создали.

Проблема:
при запуске программы, она кушает 10 056 КБ (у меня на win7). После двадцати нажатий на кнопку «Create pic»/«Delete picture», уже кушает 10 156, после 100 нажатий — 10212 КБ.
То есть медленно, но растет.

В данном случае потери небольшие.
Но если сделать игру в канвасе, где постоянно появляются и исчезают картинки (по несколько штук за одно нажатие): http://python.su/forum/topic/24887/
, то скорость утечки будет намного больше и через какое-то время программа начинает тормозить, а потом зависает.

Вопрос:
из-за чего эта утечка памяти и как ее избежать?

Подозреваю, что GC не отдает всю память, но манипуляции с gc.collect() не помогают.

В аттаче архив с .py файлом и картинкой.
WoMax
что удалось найти в сети:
http://python.6.x6.nabble.com/Memory-leak-with-tkinter-canvas-itemconfigure-td1975033.html
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB