[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyQt] Debug potential memory leaks
From:       Andreas Pakulat <apaku () gmx ! de>
Date:       2015-04-08 21:52:06
Message-ID: CAExHGmRKeQ+HOhrGuk3ZtC-CD+yr47ESbB9wBHzj9AqHQctegg () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi,

On Wed, Apr 8, 2015 at 10:42 AM, Andreas Pakulat <apaku@gmx.de> wrote:

> Hi Phil,
>
> On Tue, Apr 7, 2015 at 9:55 PM, Phil Thompson <phil@riverbankcomputing.com
> > wrote:
>
>> On 07/04/2015 8:47 pm, Andreas Pakulat wrote:
>>
>>> Hi,
>>>
>>> I'm having a small 'systray' application that monitors a jenkins service
>>> and it seems there's some kind of memory leak, especially on MacOSX.
>>> After
>>> having it run for a while (with the machine going to sleep now and again)
>>> it starts eating quite some memory - if I understand top/ActivityMonitor
>>> correctly - and amd wondering now how I'd best debug a PyQt application's
>>> memory consumption.
>>>
>>> So what tools do you guys usually use to debug such memory leaks? I've
>>> tried valgrind on Linux but there's no good hint there, possibly also due
>>> to the way Python works.
>>>
>>
>> You could try a debug version of Python that will track objects. If that
>> shows objects are not being collected then it is probably a PyQt problem.
>> Otherwise it might be more likely to be a Qt problem.
>
>
> I'll check that option if I can determine its not my own code hanging on
> to objects it shouldn't hang onto anymore...
>

So, it seems like I'm leaking QAction's and they're not garbage-collected
for quite a while even when they're not connected to anymore anymore. I can
'fix' the problem by setting their parent QObject to None and explicitly
calling gc.collect, without the latter the objgraph module (
http://mg.pov.lt/objgraph.py) shows them as  objects without any references
to them even after another minute of the application running.

Maybe a little background on what the app does helps to understand this a
little better. It polls a jenkins instance for states of the various jobs
and for each job a QAction is created and added to the menu of a QSysTray
object. Each time the data is retrieved all existing QActions are removed
from teh menu via removeAction and the dictionary that kept the instances
is cleared. Then a new set of actions is created and added to the menu for
the possibly-changed set of jobs and their changed icons. The parent object
of the actions is the systray's menu, hence having to set their parent to
None when I want to get rid of them makes sense.

What I find surprising though is that Python's gc does not clean them up
even after a while unless I explicitly call gc.collect. Does someone have
an explanation for this?

Andreas

[Attachment #5 (text/html)]

<div dir="ltr">Hi,<div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr \
8, 2015 at 10:42 AM, Andreas Pakulat <span dir="ltr">&lt;<a \
href="mailto:apaku@gmx.de" target="_blank">apaku@gmx.de</a>&gt;</span> \
wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div \
dir="ltr">Hi Phil,<div class="gmail_extra"><br><div class="gmail_quote"><span \
class="">On Tue, Apr 7, 2015 at 9:55 PM, Phil Thompson <span dir="ltr">&lt;<a \
href="mailto:phil@riverbankcomputing.com" \
target="_blank">phil@riverbankcomputing.com</a>&gt;</span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div>On \
07/04/2015 8:47 pm, Andreas Pakulat wrote:<br> <blockquote class="gmail_quote" \
style="margin:0px 0px 0px \
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
 Hi,<br>
<br>
I&#39;m having a small &#39;systray&#39; application that monitors a jenkins \
service<br> and it seems there&#39;s some kind of memory leak, especially on MacOSX. \
After<br> having it run for a while (with the machine going to sleep now and \
again)<br> it starts eating quite some memory - if I understand \
top/ActivityMonitor<br> correctly - and amd wondering now how I&#39;d best debug a \
PyQt application&#39;s<br> memory consumption.<br>
<br>
So what tools do you guys usually use to debug such memory leaks? I&#39;ve<br>
tried valgrind on Linux but there&#39;s no good hint there, possibly also due<br>
to the way Python works.<br>
</blockquote>
<br></div></div>
You could try a debug version of Python that will track objects. If that shows \
objects are not being collected then it is probably a PyQt problem. Otherwise it \
might be more likely to be a Qt \
problem.</blockquote><div><br></div></span><div>I&#39;ll check that option if I can \
determine its not my own code hanging on to objects it shouldn&#39;t hang onto \
anymore...</div></div></div></div></blockquote><div><br></div><div>So, it seems like \
I&#39;m leaking QAction&#39;s and they&#39;re not garbage-collected for quite a while \
even when they&#39;re not connected to anymore anymore. I can &#39;fix&#39; the \
problem by setting their parent QObject to None and explicitly calling gc.collect, \
without the latter the objgraph module (<a \
href="http://mg.pov.lt/objgraph.py">http://mg.pov.lt/objgraph.py</a>) shows them as   \
objects without any references to them even after another minute of the application \
running.</div><div><br></div><div>Maybe a little background on what the app does \
helps to understand this a little better. It polls a jenkins instance for states of \
the various jobs and for each job a QAction is created and added to the menu of a \
QSysTray object. Each time the data is retrieved all existing QActions are removed \
from teh menu via removeAction and the dictionary that kept the instances is cleared. \
Then a new set of actions is created and added to the menu for the possibly-changed \
set of jobs and their changed icons. The parent object of the actions is the \
systray&#39;s menu, hence having to set their parent to None when I want to get rid \
of them makes sense.</div><div><br></div><div>What I find surprising though is that \
Python&#39;s gc does not clean them up even after a while unless I explicitly call \
gc.collect. Does someone have an explanation for \
this?</div><div><br></div><div>Andreas</div></div></div></div>


[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic