Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 1, 2017 18:01:02

Guljaca
От:
Зарегистрирован: 2011-07-11
Сообщения: 93
Репутация: +  0  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

В коде ниже показан пример, постоянно отображающий одно и тоже изображение.
В течении нескольких секунд расход оперативной памяти достигает 300 мб и продолжает расти.
Пробовал cg, close(), del.
Как освобождать оперативную память?
Как отследить, что конкретно в ней хранится в данный момент. (объекты и прочее)

from tkinter import *
from PIL import Image,ImageTk
import random
root = Tk()
root.geometry("900x900+100+100")
frame = Frame(root)
frame.pack()
text = Text(frame)

image_d = {}
ph_image_d = {}

def image():
name = random.random()
image_d[name] = Image.open("image/test.jpeg")
ph_image_d[name]= ImageTk.PhotoImage(image_d[name])
text.pack()
text.image_create(END,image=ph_image_d[name])
del image_d[name]


def loop():
print(1)
text.delete('1.0', END)
root.after(100, image())
root.update()
loop()

root.bind('<ntilde>', loop()) # c


image()
root.mainloop()
print(1)



Офлайн

#2 Дек. 1, 2017 22:58:37

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

чутка про память и пайтон
https://habrahabr.ru/company/mailru/blog/336156/
https://habrahabr.ru/post/193890/
а вообще есть простое правило: В пайтоне любой обьект хранится в памяти до тех пор пока на него указывает хотябы одна переменная.
то что вы делаете

del image_d[name]
оно как мертвому припарка.
Вызов del x не приводит напрямую к вызову x.__del__(), а лишь уменьшает значение счётчика ссылок на единицу. Описываемый метод же будет вызван, только когда счётчик ссылок достигнет нуля.
А у вас кроме елемента словаря image_d на картинку в памяти ссылаеться ImageTk.PhotoImage в словаре ph_image_d, его то вы не удаляете, вот обьект и висит в памяти, а словарь image_d пухнет каждую секунду.

А вообще у вас код странный до абсурда, может вы расскажете что вы пытаетесь сделать таким чудным образом?



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Дек. 1, 2017 23:03:49)

Офлайн

#3 Дек. 1, 2017 23:29:16

Guljaca
От:
Зарегистрирован: 2011-07-11
Сообщения: 93
Репутация: +  0  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

Данный код должен был показать проблему. Вообще, он должен был срабатывать при нажатии С, но что-то пошло не так.
Пару дней я не смогу писать код. Был бы признателен, если кто-нибудь перепишет скрипт так, чтобы он не устраивал утечку памяти. Как пример. После уже буду разбираться со всем этим делом.

За информацию спасибо. Ознакомлюсь.



Отредактировано Guljaca (Дек. 1, 2017 23:29:49)

Офлайн

#4 Дек. 2, 2017 15:08:22

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

Guljaca
Был бы признателен, если кто-нибудь перепишет скрипт так, чтобы он не устраивал утечку памяти. Как пример. После уже буду разбираться со всем этим делом.
чтобы чтото написать нужно понимать что ваш скрипт должен делать, я честно говоря даже близко не понимаю что он должен делать.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#5 Дек. 2, 2017 21:31:36

Guljaca
От:
Зарегистрирован: 2011-07-11
Сообщения: 93
Репутация: +  0  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

PEHDOM
Должен при открытии нового изображения (не обязательно того же), и помещения его на место предыдущего, выгружать информацию о предыдущем из памяти.
Как пример, представь, что это книга с картинками, которую листает ребенок. Пролистав всю книгу, он забьет ей всю память ПК, что не есть хорошо.
Вот у меня прога, примерно как эта книга, только я не могу весь код сюда выложить, поэтому описал ее работу и возникающую при работе проблему.
Если при каждом вызове loop, будет высвобождаться оперативная память, к примеру, это и будет решением моей проблемы.



Офлайн

#6 Дек. 3, 2017 00:01:36

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

Guljaca
Должен при открытии нового изображения (не обязательно того же), и помещения его на место предыдущего, выгружать информацию о предыдущем из памяти.
Как пример, представь, что это книга с картинками, которую листает ребенок.
O.o, честно в жизни бы не догадался потому как ваш код делает что угодно только не то что вы описали.
 name = random.random() # зачем вам каждый раз случайное имя?
  image_d[name]  = Image.open("image/test.jpeg") # зачем его заносить в словарь?
  ph_image_d[name]= ImageTk.PhotoImage(image_d[name]) # зачем заносить в словарь экземпляр PhotoImage?
...
def loop():
  ......
  loop()  # зачем вам рекурсия? Tkinter событийноориентированая библиотека, у нее есть свой цикл обработки событий.

Guljaca
Если при каждом вызове loop, будет высвобождаться оперативная память, к примеру, это и будет решением моей проблемы.
Зачем??? не занимайтесь ерундой, я уже писал в пайтоне обьект храниться в памяти ровно до тех пор пока на негу указывает хотябы одна переменна, храните картинку в переменной, потом следующую связывайте с тойже переменной, сборщик мусора сам освободит память, увидев что на обьект не осталось ссылок. Примерно так:
 from tkinter import *
from PIL import Image,ImageTk
import random
root = Tk()
root.geometry("900x900+100+100")
frame = Frame(root)
frame.pack()
text = Text(frame)
text.pack()
def add_image(event):
    text.delete('1.0', END)    # Удаляем все из text
    text.img = ImageTk.PhotoImage(Image.open('run_4135.png'))  #создаем обьект PhotoImage из файла run_4135.png и связываем с text.img
    text.image_create(END,image=text.img) # помещем картинку на text
root.bind('<ntilde>',   add_image) # картинка будет добавляться на text при нажатии русской "с"
root.mainloop()
print(1)



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Дек. 3, 2017 00:20:22)

Офлайн

#7 Дек. 3, 2017 22:19:20

Guljaca
От:
Зарегистрирован: 2011-07-11
Сообщения: 93
Репутация: +  0  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

Это все нужно, чтобы вводить заранее неизвестное число изображений (в том числе и одинаковых), в поле текста. Полагаю, если сделать, как указали вы, отображаться будет только одно изображение, хранящееся в text.img и добавленное последним.
Вот скрин с работы. На входе, текст, на выходе то, что на скрине. Текст может быть любой. В том числе и содержащий сотни ссылок на одинаковые изображения.
http://s016.radikal.ru/i335/1712/22/d94c1e1fe386.jpg

Попробовал ваш код подогнать под задачу - получилось на пробе. Попробую использовать в скрипте.
Полагаю, проблема в моем недостаточном понимании чего-то, поскольку я, изучив основы, сразу к практике перехожу. Можно сказать, работаю молотком и рубанком.
Почерпнул для себя пару занятных моментов. Особо интересно было про RAM узнать. Спасибо.



Отредактировано Guljaca (Дек. 3, 2017 23:13:55)

Офлайн

#8 Дек. 4, 2017 09:38:59

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.

Guljaca
Полагаю, если сделать, как указали вы, отображаться будет только одно изображение, хранящееся в text.img и добавленное последним
естественно, я же исходил из вашего примера, у вас только одно изображение в примере. Но алгоритм в целом один и тот же и может незначительно меняться в зависимости от того сколько одновременно картинок должно(может) выводиться на экран одновременно. Я честно говоря, изначально думал что вы хотите реализовать некое подобие смайлов, но потом вы заговорили про книгу, то-есть единовременно в памяти(на экране) должна быть одна картинка. Если у вас список картинок которые нужно показать по одной в определеной последовательности, то загоняйте по одной в переменную, если тот же список нужно показать по несколько картинок, загоняйте их в список, если у вас чтото по типу смайлов, то создавайте словарь.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Дек. 4, 2017 09:39:15)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version