Форум сайта python.su
Будьте добры помогите разобраться.
Имеет ли данный код утечку памяти?
При удаление класса должен выполняться __del__, но все они выполняются при закрытии основного окна.
В данном случае можно предположить что то остается в памяти после удалении класса.
Можно ли использовать данный метод если дополнительные окна создаются и удаляются много раз?
# -*- coding: utf-8 -*- import tkinter as tk import gc class win(): num = 0 def __init__(self, root, perent) -> None: self.root = root self.parent = perent win.num += 1 self.tl = tk.Toplevel(self.root) # self.tl.geometry("600x400+100+100") self.tl.geometry("600x400") self.fr = tk.Frame(self.tl) self.fr.pack() self.lb = tk.Label(self.fr, text=str(win.num)) self. lb.pack() self.bt = tk.Button(self.fr, text='Закрыть окно', command=self.exit1) self.bt.pack() def active(self): self.tl.mainloop() def exit1(self): # self.tl.destroy() self.parent.win_del() def __del__(self): print('__del__'*5) class wroot(): ltp = [] def __init__(self): self.root = tk.Tk() self.root.geometry("800x600+10+10") self.fr = tk.Frame(self.root) self.fr.pack() self.bt = tk.Button(self.fr, text='Добавить окно', command=self.start) self.bt.pack() self.bt1 = tk.Button(self.fr, text='Удалить окно', command=self.win_del) self.bt1.pack() self.root.mainloop() def start(self): wroot.ltp.append(win(self.root, self)) wroot.ltp[-1].active() def win_del(self): if len(wroot.ltp) > 0: wroot.ltp[-1].bt.destroy() wroot.ltp[-1].fr.destroy() wroot.ltp[-1].tl.destroy() for obj in gc.get_referrers(wroot.ltp[-1]): print(':'*3, obj) print('\n') # mroot.ltp.pop() del wroot.ltp[-1] print(gc.garbage) print('\n') if __name__ == '__main__': w = wroot()
Отредактировано v3_62 (Дек. 16, 2021 18:22:34)
Офлайн
v3_62нет не должен, __del__ вызывается когда счетчик ссылок на обьект становиться равен нулю.
При удаление класса должен выполняться __del__, но все они выполняются при закрытии основного окна.
[code python][/code]
Отредактировано PEHDOM (Дек. 15, 2021 17:27:41)
Офлайн
Получается что в __del__ нельзя писать код который должен выполняться при удаление объекта.
Если объект удален, то как можно посмотреть какие ссылки не него остались?
Если объект удален, то сборщик мусора должен поставить его в очередь на удаление,
если удалить не удается, то объект должен остаться в этой очереди до
удаления ссылок. Если я правильно понимаю gc.garbage должен показать
такие объект в списке, но список пустой.
В реальной задаче объекты могу создаваться и удаляться более
1000 раз и хочется быть уверенным, что данный подход годен для использования.
Отредактировано v3_62 (Дек. 15, 2021 18:48:05)
Офлайн
v3_62Прежде чем писать на Tkinter, почитай что-нибудь про Tkinter, рассмотри примеры программ. Не мешает ещё про Tcl/Tk почитать.
Будьте добры помогите разобраться.
v3_62А это Творение можешь смело стирать.
В реальной задаче объекты могу создаваться и удаляться более
1000 раз и хочется быть уверенным, что данный подход годен для использования.
v3_62Если тебе понадобился gc, значит ты что-то не то делаешь. Вряд ли он тебе понадобится, если ты будешь правильно код писать.
Если я правильно понимаю gc.garbage должен показать
такие объект в списке
Офлайн
Спасибо за советы и ответ.
Если тебе понадобился gc, значит ты что-то не то делаешь. Вряд ли он тебе понадобится, если ты будешь правильно код писать.
Отредактировано v3_62 (Дек. 16, 2021 13:08:17)
Офлайн
v3_62Исходники питона, как и исходники Tkinter лежат в открытом доступе. Там можно всё прочитать, что и как там работает. Но ты их не поймёшь, потому что по твоему Великому Коду видно, что ты находишься на начальном уровне каком-то там.
Для того что бы правильно писать код надо понимать как работает python c tkinte
Офлайн
v3_62ну вобщем да, по ссылке что давал написаны причины по которым счетчик может не дойти до нуля.
Получается что в __del__ нельзя писать код который должен выполняться при удаление объекта.
v3_62ЕМНИП никак, у смого обьекта есть только счетчик ссылок, но он в общем не в курсе кто на него хранит ссылку.
Если объект удален, то как можно посмотреть какие ссылки не него остались?
v3_62нет del X просто уменьшает счетчик обьекта на 1, а уже сборщик проходя по обьектам смотрит на счетчик и решает удалять из памяти или нет. Там конечно еще алгоритмы поиска слабых и циклических ссылок, но вобщем и целом както так.
если объект удален, то сборщик мусора должен поставить его в очередь на удаление,
если удалить не удается, то объект должен остаться в этой очереди до
удаления ссылок.
v3_62у ткинтера под капотом твориться какоето колдунство, вот тут https://stackoverflow.com/questions/52839050/why-doesnt-tkinter-release-memory-when-an-instance-is-destroyed чутка поподробнее, но вобщем чтобы понять что там за магия нужно очень глубоко лезть в дебри ткинтера.
Если я правильно понимаю gc.garbage должен показать
такие объект в списке, но список пустой.
[code python][/code]
Отредактировано PEHDOM (Дек. 16, 2021 18:01:51)
Офлайн
py.user.next;)))
Исходники питона, как и исходники Tkinter лежат в открытом доступе. Там можно всё прочитать, что и как там работает. Но ты их не поймёшь, потому что по твоему Великому Коду видно, что ты находишься на начальном уровне каком-то там.
py.user.nextВ документации как правило элементарные примеры - пояснения. Единственный способ смотреть чужой код.
Читай документацию, там куча примеров и все правильные.
Офлайн
v3_62Вот пример
А чем код не понравился? Он написан для примера, самый элементарный
v3_62Оно должно быть записано вот такclass win(): num = 0
class Win: num = 0
v3_62Сразу же возникает ряд вопросов к нему. Если win - это класс, то root справа от знака равно из первой строки - это класс или экземпляр класса? Если win - это класс, то perent справа от знака равно из первой строки - это класс или экземпляр класса? Если win - это класс, то self слева от знака равно из первой строки - это класс или экземпляр класса?self.root = root self.parent = perent win.num += 1
class Win: num = 0 win = Win() win1 = win
win.num += 1 Win.num += 1
v3_62Из-за того, что ты так пишешь безграмотно, никто не станет читать твой код с кучей строк. Зачем тратить время на расшифровку безграмотного кода? вряд ли в безграмотном коде будет что-то умное в алгоритмическом плане. Очень велика вероятность того, что автор безграмотного кода строит и алгоритмы безграмотно. Придётся ещё алгоритмы разгребать.
выкладывать реальный код с кучей строк не относящегося к вопросу глупо
v3_62Видно, что ты занимаешься ерундой, потому что не понимаешь даже, для чего элементы прикрепляются друг к другу при их создании. Дочерние элементы прикрепляются к родительским.if len(wroot.ltp) > 0: wroot.ltp[-1].bt.destroy() wroot.ltp[-1].fr.destroy() wroot.ltp[-1].tl.destroy()
wroot.ltp[-1].destroy()
Отредактировано py.user.next (Дек. 20, 2021 08:41:20)
Офлайн
v3_62Может взять какой-нибудь инструмент для тестирования,который бы показал количество памяти с окнами и без окон по факту, на подобии memory profiler?
Имеет ли данный код утечку памяти?
Офлайн