Logging 在Windows中,使用PyQt4和PySide从QThread记录内存泄漏,而不是从Python线程记录
在QThread中使用“logging”模块时,我看到在Windows中运行时内存泄漏。在Python3中使用PySide和PyQt4都会发生这种情况 在Linux中,没有内存泄漏 下面的程序演示了这个问题。它可以用三种方式调用 在没有参数的情况下运行会使用Python线程,并且不会出现泄漏:Logging 在Windows中,使用PyQt4和PySide从QThread记录内存泄漏,而不是从Python线程记录,logging,pyqt4,pyside,python-multithreading,Logging,Pyqt4,Pyside,Python Multithreading,在QThread中使用“logging”模块时,我看到在Windows中运行时内存泄漏。在Python3中使用PySide和PyQt4都会发生这种情况 在Linux中,没有内存泄漏 下面的程序演示了这个问题。它可以用三种方式调用 在没有参数的情况下运行会使用Python线程,并且不会出现泄漏: D:\> python MemoryLeak.py gc objects: 8965 WARNING:root:hi there! gc objects: 8987 WARNING:root:hi
D:\> python MemoryLeak.py
gc objects: 8965
WARNING:root:hi there!
gc objects: 8987
WARNING:root:hi there!
gc objects: 8987
WARNING:root:hi there!
gc objects: 8987
WARNING:root:hi there!
(... etcetera ...)
使用单个“-qt”参数运行时,通过Qt4使用QThreads,在Windows中使用泄漏,但在Linux中不使用:
D:\>python MemoryLeak.py --qt
gc objects: 8975
WARNING:root:hi there!
gc objects: 9000
WARNING:root:hi there!
gc objects: 9010
WARNING:root:hi there!
gc objects: 9020
WARNING:root:hi there!
gc objects: 9030
WARNING:root:hi there!
gc objects: 9040
WARNING:root:hi there!
(... etcetera ...)
D:\>python MemoryLeak.py --qt --pyside
gc objects: 15076
WARNING:root:hi there!
gc objects: 15093
WARNING:root:hi there!
gc objects: 15103
WARNING:root:hi there!
gc objects: 15113
WARNING:root:hi there!
gc objects: 15123
WARNING:root:hi there!
gc objects: 15133
WARNING:root:hi there!
gc objects: 15143
(... etcetera...)
使用“-qt”和“-pyside”参数运行时,通过pyside使用QThreads,在Windows中使用漏洞,但在Linux中不使用:
D:\>python MemoryLeak.py --qt
gc objects: 8975
WARNING:root:hi there!
gc objects: 9000
WARNING:root:hi there!
gc objects: 9010
WARNING:root:hi there!
gc objects: 9020
WARNING:root:hi there!
gc objects: 9030
WARNING:root:hi there!
gc objects: 9040
WARNING:root:hi there!
(... etcetera ...)
D:\>python MemoryLeak.py --qt --pyside
gc objects: 15076
WARNING:root:hi there!
gc objects: 15093
WARNING:root:hi there!
gc objects: 15103
WARNING:root:hi there!
gc objects: 15113
WARNING:root:hi there!
gc objects: 15123
WARNING:root:hi there!
gc objects: 15133
WARNING:root:hi there!
gc objects: 15143
(... etcetera...)
我在Windows下使用的是基于Python 3.3.5的WinPython 3.3.5
我的完整测试计划:
#! /usr/bin/env python3
import sys, time, logging, gc, threading
if "--pyside" in sys.argv:
from PySide import QtCore
QtSlot = QtCore.Slot
else:
from PyQt4 import QtCore
QtSlot = QtCore.pyqtSlot
def gc_status():
gc.collect(0)
gc.collect(1)
gc.collect(2)
print("gc objects:", len(gc.get_objects()))
class MyQtThread(QtCore.QThread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def run(self):
logging.warning("hi there!")
class MyQtApplication(QtCore.QCoreApplication):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._count = 0
self._timer = QtCore.QTimer()
self._timer.timeout.connect(self._timer_timeout)
self._timer.start(200)
@QtSlot()
def _timer_timeout(self):
gc_status()
t = MyQtThread()
t.start()
t.wait()
self._count += 1
if self._count == 50:
self.quit()
def qt_main():
app = MyQtApplication(sys.argv)
app.exec_()
class PythonThread(threading.Thread):
def __init__(self):
super().__init__()
def run(self):
logging.warning("hi there!")
def python_main():
for i in range(50):
gc_status()
t = PythonThread()
t.start()
t.join()
time.sleep(0.200)
if "--qt" in sys.argv:
qt_main()
else:
python_main()
这是一个已知的问题/错误吗?还是我做错了什么?我刚刚尝试了Python2.7(最新的PyQt4)并看到了同样的结果。我认为这可能是日志模块的问题,而不是PyQt/PySide的问题。我分析了泄漏的内容,它是一堆Python字典和列表,因此我猜如果在Python线程之外使用日志模块,日志模块不知道如何清理它自己。我在Windows 7上的Python 3.4.2 64位上尝试了PySide 1.2.2,但没有发现泄漏。