Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 24, 2012 11:51:31

spirits25
От:
Зарегистрирован: 2011-09-29
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Утечка памяти

Всем привет.
почему процесс начинает кушать всё больше и больше памяти??? На моей машине потребление памяти плавно поднимается с 0.8% до 1.2%.

from PySide import QtGui, QtCore
import datetime, sys
import gc

class MyWgt(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)

self.ld = []
for i in range (20):
self.ld.append(QtGui.QLabel(self))

for i in self.ld:
i.deleteLater()
del self.ld

self.setAttribute(QtCore.Qt.WA_DeleteOnClose)


app = QtGui.QApplication(sys.argv)

gc.enable()
for i in range (10000):
print i
ex = MyWgt()
ex.show()
ex.close()

# как его удалить??????
ex.destroy()
del ex

if i % 10 == 0:
gc.collect()


i = 0
while (True):
if i < 100000:
i += 1
else:
i = 0

sys.exit(1)
Причём если не делать show для виджета, то память не уходит. Почему мусорщик не хочет очищать память, если виджет был показан? или как заставить его убрать этот мусор?
Спасибо.



Офлайн

#2 Фев. 24, 2012 13:55:57

dartNNN
От:
Зарегистрирован: 2009-12-08
Сообщения: 199
Репутация: +  0  -
Профиль   Отправить e-mail  

Утечка памяти

Не знаю есть ли смысл все рассказывать, но я попробую:)
Во-первых. В питоне автоматическая сборка мусора. АВТОМАТИЧЕСКАЯ СБОРКА МУСОРА!!!
И ваши строчки типа
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
gc.enable()
ex.destroy()
del ex
gc.collect()
Чистейший бред.
Во-вторых последили бы за форматированием в блоке кода, для питона это критически важно, да и читать невозможно.
Теперь по существу:)
Вы знаете что делает функция deleteLater() ?
Она говорит, что объект будет удален, когда управление будет возвращено в event loop. Это главный цикл любого гуи приложения, через который передаются все события. Если event loop не запущен, то объект будет удален после его запуска. И как же он запускается? Да вот так: sys.exit(app.exec_()) (эта строчка есть в ЛЮБОМ ПРИМЕРЕ PyQt, уж потрудились бы посмотреть).
Так и хочется сказать: не знаешь, не трогай! Маленький еще.



Офлайн

#3 Фев. 24, 2012 14:22:27

spirits25
От:
Зарегистрирован: 2011-09-29
Сообщения: 18
Репутация: +  0  -
Профиль   Отправить e-mail  

Утечка памяти

dartNNN
Да вот так: sys.exit(app.exec_()) (эта строчка есть в ЛЮБОМ ПРИМЕРЕ PyQt, уж потрудились бы посмотреть).
И у меня это сначало было, но результат тот же.

Без этих строк:
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
gc.enable()
ex.destroy()
del ex
gc.collect()
результат тот же, память растёт.

А ваша
dartNNN
АВТОМАТИЧЕСКАЯ СБОРКА МУСОРА!!!
почему то не срабатывает, когда после кучи программа доходит до строчки
sys.exit(app.exec_())
Вот первоначальный код, в котором дела ещё хуже, чем в первом:
from PySide import QtGui, QtCore
import sys

class MyWgt(QtGui.QWidget):
def __init__(self, parent):
QtGui.QWidget.__init__(self, parent)

for i in range (40):
self.t = QtGui.QLabel('', self)

app = QtGui.QApplication(sys.argv)

par = QtGui.QWidget()
for i in range (1000):
s = MyWgt(par)
s.show()
s.close()

print "END"
sys.exit(app.exec_())
За эти 1000 итераций память возростает с 0.7% до 8.1%, с каждой итерацией всё более подтупливая.
Так в чём причина??



Отредактировано (Фев. 24, 2012 14:30:21)

Офлайн

#4 Фев. 24, 2012 16:33:56

dartNNN
От:
Зарегистрирован: 2009-12-08
Сообщения: 199
Репутация: +  0  -
Профиль   Отправить e-mail  

Утечка памяти

Оп! Как интересно…. У вас какая система? Версия питона/PySide? Тут придется глубже копать. Вообще пример достаточно нестандартный (с трудом представляю, чтобы кому-нибудь в программе придется создавать 1000 окон:)) У меня сейчас под рукой нет PySide, так что начну копать в ближайшие пару дней.



Офлайн

#5 Фев. 25, 2012 08:33:31

cutwater
От:
Зарегистрирован: 2009-01-08
Сообщения: 444
Репутация: +  19  -
Профиль   Отправить e-mail  

Утечка памяти

Меня больше интересует, а с чего вообще наш многоуважаемый автор взял, что в его последнем примере память должна автоматически освобождаться до END. Прежде чем писать громкие посты “Ололо, я нашел утечку” надо бы разобраться с матчастью. Виджеты создаются в цикле как дочерние виджеты par. Исходя из этого очевидно, что все объекты будут существовать до тех пор пока жив родитель. А родитель собственно жив в данном примере до выхода из программы. Занавес.



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version