[PyQt] Is PyQt really freeing memory?

Phil Thompson phil at riverbankcomputing.com
Tue Aug 11 14:59:29 BST 2009


On Sun, 2 Aug 2009 02:12:52 +0200, Albert Cervera i Areny
<albert at nan-tic.com> wrote:
> I've been having problems with my application consuming too much memory
> after 
> some time running and today decided to take a deeper look. I've ended up
> with 
> the attach test.py script which either demonstrates PyQt is not freeing
> memory 
> appropiately when signals are involved or I simply don't understand how
> this 
> works.
> 
> As you can see the script creates lists with 100.000 QObjects and prints
> the 
> memory used. As python won't free memory but reuse what has already been
> freed 
> I expect a call like:
> 
> list = []
> fill in the list with lots of data
> 
> to take as much memory as:
> 
> list = []
> fill in the list with lots of data
> list = []
> fill in the list with the same lots of data
> 
> If you give it a try, you'll realize that this is true if you create
> 100.000 
> objects with no signal connections. But if you connect and disconnect  a 
> signal for those objects, the memory used after the second fill is larger
> than 
> after the first one.
> 
> It seems to me that some data is being leaked in connect() and
disconnect()
> 
> functions (which, by the way, take up a lot of memory).
> 
> Here's the output of the script in my system:
> 
> $ python test.py one no
> Executing 'one' without signals
> Memory:  21564
> 
> $ python test.py one yes
> Executing 'one' with signals
> Memory:  64992
> 
> $ python test.py two yes
> Executing 'two' with signals
> Memory:  125592
> 
> $ python test.py two+remove yes
> Executing 'two+remove' with signals
> Memory:  93880
> 
> $ python test.py three+remove yes
> Executing 'three+remove' with signals
> Memory:  122808
> 
> So "two+remove yes" should be using 64992 Kb (just like "one yes") but it
> uses 
> 50% more. The same happens with "three+remove yes", again more 30 Mb!

The proxies that are created to allow Python callables to be used as Qt
slots are destroyed using QObject::deleteLater(). As your example doesn't
have an event loop they never get destroyed.

In tonight's snapshot I've changed the implementation so they get destroyed
immediately as it does simplify the code a little.

Phil


More information about the PyQt mailing list