Найти - Пользователи
Полная версия: Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.
Начало » Python для новичков » Python3 + Tkinter + Pillow. Освобождение оперативной памяти RAM.
1
Guljaca
В коде ниже показан пример, постоянно отображающий одно и тоже изображение.
В течении нескольких секунд расход оперативной памяти достигает 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)
PEHDOM
чутка про память и пайтон
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 пухнет каждую секунду.

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

За информацию спасибо. Ознакомлюсь.
PEHDOM
Guljaca
Был бы признателен, если кто-нибудь перепишет скрипт так, чтобы он не устраивал утечку памяти. Как пример. После уже буду разбираться со всем этим делом.
чтобы чтото написать нужно понимать что ваш скрипт должен делать, я честно говоря даже близко не понимаю что он должен делать.
Guljaca
PEHDOM
Должен при открытии нового изображения (не обязательно того же), и помещения его на место предыдущего, выгружать информацию о предыдущем из памяти.
Как пример, представь, что это книга с картинками, которую листает ребенок. Пролистав всю книгу, он забьет ей всю память ПК, что не есть хорошо.
Вот у меня прога, примерно как эта книга, только я не могу весь код сюда выложить, поэтому описал ее работу и возникающую при работе проблему.
Если при каждом вызове loop, будет высвобождаться оперативная память, к примеру, это и будет решением моей проблемы.
PEHDOM
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)
Guljaca
Это все нужно, чтобы вводить заранее неизвестное число изображений (в том числе и одинаковых), в поле текста. Полагаю, если сделать, как указали вы, отображаться будет только одно изображение, хранящееся в text.img и добавленное последним.
Вот скрин с работы. На входе, текст, на выходе то, что на скрине. Текст может быть любой. В том числе и содержащий сотни ссылок на одинаковые изображения.
http://s016.radikal.ru/i335/1712/22/d94c1e1fe386.jpg

Попробовал ваш код подогнать под задачу - получилось на пробе. Попробую использовать в скрипте.
Полагаю, проблема в моем недостаточном понимании чего-то, поскольку я, изучив основы, сразу к практике перехожу. Можно сказать, работаю молотком и рубанком.
Почерпнул для себя пару занятных моментов. Особо интересно было про RAM узнать. Спасибо.
PEHDOM
Guljaca
Полагаю, если сделать, как указали вы, отображаться будет только одно изображение, хранящееся в text.img и добавленное последним
естественно, я же исходил из вашего примера, у вас только одно изображение в примере. Но алгоритм в целом один и тот же и может незначительно меняться в зависимости от того сколько одновременно картинок должно(может) выводиться на экран одновременно. Я честно говоря, изначально думал что вы хотите реализовать некое подобие смайлов, но потом вы заговорили про книгу, то-есть единовременно в памяти(на экране) должна быть одна картинка. Если у вас список картинок которые нужно показать по одной в определеной последовательности, то загоняйте по одной в переменную, если тот же список нужно показать по несколько картинок, загоняйте их в список, если у вас чтото по типу смайлов, то создавайте словарь.
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