<br>Thanks Giovanni, <br><br>&nbsp;&nbsp; That's very helpful.<br><br>Charles.<br><br><b><i>Giovanni Bajo &lt;rasky@develer.com&gt;</i></b> wrote:<blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"> On mar, 2007-07-31 at 13:11 -0700, charles chen wrote:<br><br>&gt; <br>&gt;    Thanks Phil for your help with our memory lapse.<br>&gt; <br>&gt;    We've come across another issue:  the Python garbage collector<br>&gt; isn't sussing out circular references properly.<br>&gt; <br>&gt;    A previous post by you say that this should be working:<br>&gt; <br>&gt; http://www.riverbankcomputing.com/pipermail/pyqt/2007-May/016237.html<br>&gt; <br>&gt;    Here's a simple demonstration:<br>&gt; <br>&gt; &gt;&gt;&gt; from PyQt4.QtCore import QObject<br>&gt; &gt;&gt;&gt; class q(QObject):<br>&gt; ...   def init(self):<br>&gt; ...     QObject.init(self)<br>&gt; ...   def __del__(self):<br>&gt; ...     print 'q deleted.'<br>&gt;
 ...<br>&gt; &gt;&gt;&gt; q1 = q()<br>&gt; &gt;&gt;&gt; q1 = None<br>&gt; q deleted.<br>&gt; &gt;&gt;&gt; q2 = q(<br>&gt; &gt;&gt;&gt; q2.circularReference = q2<br>&gt; &gt;&gt;&gt; q2 = None<br>&gt; &gt;&gt;&gt; q3 = q()<br>&gt; &gt;&gt;&gt; q3.circularReference = q3<br>&gt; &gt;&gt;&gt; q3.deleteLater()<br>&gt; &gt;&gt;&gt; q3 = None<br>&gt; &gt;&gt;&gt; import gc<br>&gt; &gt;&gt;&gt; gc.collect()<br>&gt; 0<br>&gt; &gt;&gt;&gt; q4 = q()<br>&gt; &gt;&gt;&gt; q4.circularReference = q4<br>&gt; &gt;&gt;&gt; q4.circularReference = None<br>&gt; &gt;&gt;&gt; q4 = None<br>&gt; q deleted.<br>&gt; <br>&gt;    q2 and q3 are never gc'ed.<br>&gt; <br>&gt;    We're also seeing this in production.  Are we doing something<br>&gt; wrong?  <br><br>Yes the garbage collector doesn't work with objects containing __del__.<br>That's true since GC was introduced in Python 2.0. If you activate GC<br>debug mode (via gc.set_flags() or whatever it is called), run an<br>explicit gc.collect() call,
 and look at gc.garbage, you should find your<br>q2 and q3 there, as they are classified as "uncollectable"  <br><br>Try rewriting your example without __del__ and it will work. To issue a<br>pring when an object is collected without using __del__, you have 2<br>alternatives:<br><br>a) Use Python's weakref, which allows to register a callback function<br>invoked when an object is about to be collected.<br>b) Use Qt's SIGNAL("destroyed()"), emitted by all QObjects when they are<br>in the process of being destroyed.<br><br>Either way, you will see that your objects are collected. <br><br>Notice that using a weakref internally within a class is a good way to<br>replace existing code using __del__ and make it GC-friendly.<br>-- <br>Giovanni Bajo<br><br><br></blockquote><br>