Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 29, 2014 23:17:10

WoMax
Зарегистрирован: 2014-05-26
Сообщения: 124
Репутация: +  9  -
Профиль   Отправить e-mail  

canvas + image deleting = memory leak?

Привет,
создадим канвас и кнопку:

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 (Авг. 29, 2014 23:30:28)

Прикреплённый файлы:
attachment example.zip (2,2 KБ)

Офлайн

#2 Авг. 30, 2014 00:41:34

WoMax
Зарегистрирован: 2014-05-26
Сообщения: 124
Репутация: +  9  -
Профиль   Отправить e-mail  

canvas + image deleting = memory leak?

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version