[prev in list] [next in list] [prev in thread] [next in thread]
List: pykde
Subject: [PyKDE] PyQT Memory Leak (new)
From: Nahuel Greco <nahuel () puntorojo ! com ! ar>
Date: 2005-03-23 15:51:41
Message-ID: 20050323125141.03e3c0e5.nahuel () puntorojo ! com ! ar
[Download RAW message or body]
Hi, I think that I have found a memory leak in the latest PyQT snapshot. When you
create forms, if the form constructor connects their signals, after his destruction
a "weakref" object remains in memory. Note the attached logs:
without_signal_connections.log: For this log I only pressed the second button,
so the forms were created without connecting their signals. Python objects count
remains constant, as you can see in the gc debug messages. Also the memory used
don't increases.
connecting_signals.log: Here I only pressed the first button, the forms were
created connecting their signals. This case leaks, the memory increased after
each run, and you can see in the gc debug messages that for each created form
an object of type 'weakref' remains without beign collected.
Saludos,
Nahuel Greco.
Saludos,
Nahuel Greco.
["without_signal_connections.log" (application/octet-stream)]
["connecting_signals.log" (application/octet-stream)]
["isolate_new_leak.py" (text/x-python)]
#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
import sys, os, time, gc
from qt import *
sys.stderr = sys.stdout
######### Query Memory Usage Functions ####################################
def report(s):
print s
sys.stdout.flush()
def presentMemData(s=""):
vmsize = vmrss = 0
for l in open('/proc/self/status','r').readlines():
if l.startswith('VmSize:'):
vmsize = int(l.split()[1])
elif l.startswith('VmRSS:'):
vmrss = int(l.split()[1])
report(s+"VmSize: %d Kb VmRss: %d Kb" % (vmsize,vmrss))
############################################################################
class SimpleForm(QDialog):
def __init__(self, connect_signal=True):
# Note, I'm using None as the parent
QDialog.__init__(self, None)
self.button = QPushButton(self, "Button")
if connect_signal:
self.connect(self.button, SIGNAL('clicked()'), self.buttonHandler)
def buttonHandler(self):
pass
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.last_gc_types = None
l = QVBoxLayout(self,3,3)
self.button1 = QPushButton(self)
self.button1.setText("1- Construct Forms connecting their signals")
self.button2 = QPushButton(self)
self.button2.setText("2- Construct Forms without connect their signals")
self.lab = QLabel(self)
self.lab.setText("(Check console output for Memory Usage information)")
l.addWidget(self.button1)
l.addWidget(self.button2)
l.addWidget(self.lab)
self.connect(self.button1, SIGNAL('clicked()'), self.button1Handler)
self.connect(self.button2, SIGNAL('clicked()'), self.button2Handler)
def button1Handler(self):
self.construct(True)
def button2Handler(self):
self.construct(False)
def construct(self, connect_signals):
global app
NUM_FORMS = 1000
report("-- %s - Constructing %d SimpleForm's, connecting signals=%r" % \
(time.strftime("%H:%M:%S"), NUM_FORMS, connect_signals))
for x in xrange(NUM_FORMS):
s = SimpleForm(connect_signals)
#s.exec_loop()
s = None
#report("-- End Construction - Forcing GC with lowest thresholds")
old_thresholds = gc.get_threshold()
gc.set_debug(gc.DEBUG_LEAK | gc.DEBUG_STATS)
# After this setting, gc.collect() will check all the generations
gc.set_threshold(1,1,1)
col = gc.collect()
gc.set_threshold(*old_thresholds)
gc.set_debug(0)
uncol = len(gc.garbage)
if col or uncol:
report("-- GC Collected: %d Uncollected: %d" % (col, uncol))
# Count instances by type
#lobj = None
reference_counts_by_type = {}
for obj in gc.get_objects():
t = type(obj)
if reference_counts_by_type.has_key(t):
reference_counts_by_type[t] += 1
lobj = obj
else:
reference_counts_by_type[t] = 1
#if lobj:
# report("REFERRS: %r" % gc.get_referrers(lobj))
# Dont press the button too fast, this line is for ensuring that
# the xlib memory is deallocated.
app.processEvents()
# Print the types that now have more instances
if self.last_gc_types:
report("-- Types of python objects whose number of instances increased from last command:")
for k,v in self.last_gc_types.items():
if reference_counts_by_type.has_key(k) and reference_counts_by_type[k] > v:
report("\t%r instances count: %r (+%d)" % (k,v, reference_counts_by_type[k] - v ))
self.last_gc_types = reference_counts_by_type
presentMemData("-- Memory Usage: ")
report("")
app = QApplication(sys.argv)
w = Main()
app.setMainWidget(w)
w.show()
report("QT Version: "+ qVersion())
report("PYQT Version: "+ PYQT_VERSION_STR)
report("SIP Version: "+ os.popen('sip -V').read())
presentMemData()
print
app.exec_loop()
_______________________________________________
PyKDE mailing list PyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic