[Development] leak in QMetaObject?

Olivier Goffart olivier at woboq.com
Wed Jul 20 10:41:16 CEST 2016


On Mittwoch, 20. Juli 2016 10:01:26 CEST André Somers wrote:
> Op 19/07/2016 om 18:06 schreef Olivier Goffart:
> > It is true that we could consider trying to clean the connection list
> > after
> > each signal emission if it is dirty.
> > We don't want to do it after each disconnect because this can turn a O(n)
> > algorithm into a O(n^2)   (cleaning the list is O(n), if we have to do it
> > for every disconnect, that n*O(n))
> 
> Did anyone ever measure in practice what the distribution in values for
> n is here? My *guess* is that it won't be all that large. I expect a
> distribution with a spike at n=1 or 2, and then a dropoff with a very
> long tail, perhaps spiking at a bit larger number when using QML for all
> the propertybindings going on. Big-O notation doesn't make a lot of
> sense if the n is small, it only starts to have an impact if n grows. 

The distribution does not matter. If it can be big, quadradic complexity can 
be a blocker.

> I would be suprised if the impact of the list being a single-linked list
> and thus having to skip through memory to get from node to node was not
> bigger than any "big-O" benefits you gained from doing it this way in
> the first place.

Maybe changing to a vector could be indeed beneficial. Note that it's not that 
simple as the nodes are in two different linked list at the same time. And 
this is used for efficient disconnect when a reciever is destroyed.

> On the other hand, you'd have to consider the likelyhood of another
> connect hapening after a disconnect. If that is nearly 1, then sure,
> that may be a good time to clean up. But if it is closer to 0 in reality...

It would still not be a leak since the used memory is bounded to O (maximum 
amount of connection on that object at the same time)

If you do:

 forever {
   QObject::connect(&myObject, ...);
 }

you have a leak because the amount of connection grow to infinity. but that's 
your fault.

If you do:

 forever {
   QObject::connect(&myObject, ...);
   QObject::disconnect(&myObject, ...);
 }

You have no leak. Sure, there will always be one unused node in the internal 
datastructure, but it is not a leak as the memory usage does not grow. 
And that node will be also removed when the object is destroyed.


So people have been memory profiling applications, and i don't think the 
amount of connection (and especially 'dead' connection) has been a problem.


In Thomas's example, the issue was that he made 1000's of connections, then 
disconnect them all, and the internal nodes are staying. But that should not 
be a problem as this fabricated example does not exist in practice.
For example, here is an example based on his that simulate this single shot 
connection.
http://paste.ofcode.org/Gb5y5GyzCcDVFvCgQRe3V7
This will run forever, and the memory usage should not grow.

-- 
Olivier

Woboq - Qt services and support - https://woboq.com - https://code.woboq.org




More information about the Development mailing list