使用PyQt和matplotlib时Python内存泄漏
我用Python做了一个小工具,使用PyQt来创建PNG格式的图表,用户点击一个按钮就能生成图表。最开始的几次点击一切都很顺利,但每次生成图像后,程序占用的内存就会增加大约120MB,最后导致Python崩溃。
我该如何在生成图表后释放这些内存呢?下面是我代码的简化版本:
import datetime as dt
from datetime import datetime
import os
import gc
# For Graphing
import matplotlib
from pylab import figure, show, savefig
from matplotlib import figure as matfigure
from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter, DayLocator
from matplotlib.ticker import MultipleLocator
import matplotlib.pyplot as plot
import matplotlib.ticker as ticker
# For GUI
import sys
from PyQt4 import QtGui, QtCore
class HyperGraph(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle('Title')
self.create_widgets()
def create_widgets(self):
grid = QtGui.QGridLayout()
self.generate_button = QtGui.QPushButton("Generate Graph", self)
grid.addWidget(self.generate_button, 1, 1)
QtCore.QObject.connect(self.generate_button, QtCore.SIGNAL("clicked()"), self.generate_graph)
def generate_graph(self):
try:
fig = figure()
ax = fig.add_axes([1,1,1,1])
# set title
ax.set_title('Title')
# configure x axis
plot.xlim(dt.date.today() - dt.timedelta(days=180), dt.date.today())
ax.set_xlabel('Date')
fig.set_figwidth(100)
# configure y axis
plot.ylim(0, 200)
ax.set_ylabel('Price')
fig.set_figheight(30)
# export the graph to a png file
plot.savefig('graph.png')
except:
print 'Error'
plot.close(fig)
gc.collect()
app = QtGui.QApplication(sys.argv)
hyper_graph = HyperGraph()
hyper_graph.show()
sys.exit(app.exec_())
看起来是plot.savefig('graph.png')这个命令在占用内存。
如果有人能帮忙,我会非常感激!
2 个回答
7
pyplot接口是为了方便互动使用而设计的,但如果你想把它嵌入到一个应用程序中,使用面向对象的API会更好。比如说,pyplot会记录你创建的所有图形。你的 plot.close(figure)
应该 能把它们关闭,但有可能这个命令没有被执行——你可以试着把它放在 finally
里面,或者重用同一个图形对象。
可以看看 这个例子,它展示了如何在PyQt4应用程序中使用面向对象的API嵌入matplotlib。虽然工作量会更多,但因为所有的操作都是明确的,所以你不应该因为pyplot背后自动处理的事情而出现内存泄漏。
7
看起来有些后端在出现内存泄漏的问题。你可以试着明确指定你的后端,比如这样做:
import matplotlib
matplotlib.use('Agg') # before import pylab
import pylab