[PyKDE] Memory leak: Cycles with QObject's doesn't get collected
Giovanni Bajo
rasky at develer.com
Fri Jun 17 17:36:36 BST 2005
Phil Thompson <phil at riverbankcomputing.co.uk> wrote:
>> I think I have found another memory leak. When you create cycles with
>> QObjects they aren't collected. This doesn't happen with pure python
>> objects (as expected), but in that case I have found an strange behaviour
>> when you set the gc.DEBUG_SAVEALL flag (that isn't PyQT related, but take
>> that in account if you add gc debug flags). See the attached script and
>> their logs.
>
> That's because SIP has never supported the cyclic garbage collector. That
is
> now fixed and your test script shows no leak.
I just verified that the same script *does* cause a memory leak if you use
QWidget instead of QObject as test class:
Is GC enabled?: 1
Has TestClass a __del__ method? (if True, it will be marked as unreachable):
False
PY Version: 2.3.4 (#1, Feb 2 2005, 12:11:53)
[GCC 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)]
QT Version: 3.3.4
PYQT Version: snapshot-20050417
SIP Version: 4.2.1 (snapshot-20050430-314)
VmSize: 25320 Kb VmRss: 8732 Kb
VmSize: 25320 Kb VmRss: 8736 Kb
VmSize: 25320 Kb VmRss: 8744 Kb
VmSize: 25320 Kb VmRss: 8748 Kb
VmSize: 25320 Kb VmRss: 8756 Kb
VmSize: 25320 Kb VmRss: 8764 Kb
VmSize: 25320 Kb VmRss: 8768 Kb
VmSize: 25320 Kb VmRss: 8776 Kb
VmSize: 25320 Kb VmRss: 8784 Kb
VmSize: 25320 Kb VmRss: 8788 Kb
VmSize: 25320 Kb VmRss: 8796 Kb
VmSize: 25320 Kb VmRss: 8804 Kb
VmSize: 25320 Kb VmRss: 8808 Kb
VmSize: 25320 Kb VmRss: 8816 Kb
[...]
I have attached the updated script.
--
Giovanni Bajo
-------------- next part --------------
#!/usr/bin/env python
from qt import *
import sys, os, gc
######### 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))
###########################################################################
import sip
class TestClass(QWidget):
pass
app = QApplication([])
## Warning, if you uncomment the following line, then the script will leak
## even without using the QObject class. This is because the DEBUG_SAVEALL
## setting is enabled, but is strange because with that flag, only
## unreacheable objects (that is, objects with a __del__ method, see the
## gc module documentation) are saved, and that cant be the case of the
## QObject class or the pure python one.
#gc.set_debug(gc.DEBUG_LEAK | gc.DEBUG_STATS)
# This is enabled by default, just in case.
gc.enable()
# After this setting, gc.collect() will check all the generations
gc.set_threshold(1,1,1)
report("Is GC enabled?: %r" % gc.isenabled())
report("Has TestClass a __del__ method? (if True, it will be marked as unreachable): %r" % hasattr(TestClass(), '__del__'))
report("PY Version: "+ sys.version)
report("QT Version: "+ qVersion())
report("PYQT Version: "+ PYQT_VERSION_STR)
report("SIP Version: "+ os.popen('sip -V').read())
presentMemData()
for i in xrange(100):
for j in xrange(50):
a = TestClass(None)
b = TestClass(None)
a.payload = ("%r"%a)*100
a.win = b
b.win = a
# uncomment the following line when using QObject to disable the leak
#b.win = None
a = None # redundant
b = None # redundant
gc.collect()
presentMemData()
More information about the PyQt
mailing list