-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Memory leak with %matplotlib qt, with simple fix #14240
Description
When using matplotlib event loop integration (e.g. %matplotlib) with pyqt, there is a memory leak caused by a misunderstanding of the lifespan of QObjects.
I found it because I'm trying to debug slowdowns in long-running IPython sessions with autoreload. I'm not sure that this is actually the cause, but it's certainly ugly. Within a session which has been open for a couple of weeks I found:
>>> collections.Counter(map(type, gc.get_objects())).most_common(5)
[(PyQt5.QtCore.QEventLoop, 1718061),
(dict, 1006864),
(list, 702602),
(ast.Name, 267460),
(ast.Attribute, 96929)]
There are 1.7m QEventLoop instances kicking around. They are being created by IPython.terminal.pt_inputhooks.qt.inputhook on line 58, with event_loop = QtCore.QEventLoop(app). But QEventLoop is a QObject subclass, which means that passing app in the constructor parents the instance to app, so even when it exits the scope it won't be deleted, even though it's no longer needed by that point.
The fix is simple: just add a line at the end of that function containing event_loop.setParent(None).
Hopefully it's faster for you to just add that single line of code rather than me forking, making a pull request etc, but please tell me if you need me to do so.