[PyQt] Possible memory leak with signal connections

Phil Thompson phil at riverbankcomputing.com
Wed Sep 25 14:17:21 BST 2019


On 19/09/2019 19:53, Kevin Keating wrote:
> I've found what appears to be a memory leak caused by connecting
> signals to slots that lack a QtCore.pyqtSlot decorator.  I know that
> connections without the pyqtSlot decorator are expected to use more
> memory than connections with the decorator based on
> https://www.codeproject.com/Articles/1123088/PyQt-signal-slot-connection-performance. 
> In the script I've pasted below, though, connections without the
> pyqtSlot decorator continue to consume memory even after the signal
> has been disconnected and the QObjects have been discarded.  The
> script does the following:
>   - Instantiates a bunch of SignalObjects, which are QObjects with a
> signal, and stores the SingalObjects in a list.
>   - Instantiates a bunch of SlotObjects, which are QObjects with
> slots.  Each SlotObject slot is connected to the signals from all the
> SignalObjects.  The SlotObjects are then immediately discarded.
>   - Discards all SignalObjects.
>   - Runs gc.collect()
>   - Runs the QApplication's event loop for a second in case there are
> any pending DeferredDelete events.
> 
> If the SlotObject class uses the QtCore.pyqtSlot decorator, then
> memory usage at the end of the script is the same as what it was at
> the beginning of the script, which makes sense since all the objects
> that get created should be completely destroyed before the script
> finishes.  Here's the output that I get with pyqtSlot decorators:
>         Memory before signal_objects creation: 17.1MiB
>         Memory before slot objects creation: 17.1MiB
>                 Difference: 0.0B
>         Memory after slot objects creation: 17.1MiB
>                 Difference: 0.0B
>         Memory after event loop runs: 17.1MiB
>                 Difference: 0.0B
> If the SlotObject class doesn't use the QtCore.pyqtSlot decorator,
> though, then memory usage at the end of the script is substantially
> higher.  Here's the output that I get without pyqtSlot decorators:
>         Memory before signal_objects creation: 17.0MiB
>         Memory before slot objects creation: 17.0MiB
>                 Difference: 0.0B
>         Memory after slot objects creation: 210.6MiB
>                 Difference: 193.5MiB
>         Memory after event loop runs: 210.6MiB
>                 Difference: 193.5MiB
> Is this expected behavior?  Without pyqtSlot decorators, is there
> anything I can do to recover the 193 MiB of memory other than
> terminating the process?  Thanks!
> 
> I've tested the script with Python 3.6.2, PyQt 5.12.2, and Qt 5.12.3
> on Windows 10, Linux, and Mac OS.  I've also tested with Python 3.6.5,
> PyQt 5.13.1, and Qt 5.13.1 on Windows 10.  All of them give similar
> results.  The script requires the psutil package
> (https://pypi.org/project/psutil/) to monitor memory usage.

Are you expecting that the Python interpreter will return unused memory 
to the operating system?

Phil


More information about the PyQt mailing list