【发布时间】:2013-04-18 10:51:45
【问题描述】:
我有一个运行循环的 python 脚本。在这个循环中,函数DoDebugInfo 被调用,每次循环迭代一次。这个函数基本上是使用matplotlib打印一些图片到硬盘,导出一个KML文件并做一些其他的计算,什么都不返回。
我遇到的问题是,python 每次运行时,函数 DoDebugInfo 都会消耗越来越多的 RAM。我猜一些变量正在增加每个循环的大小。
我在通话前后添加了以下几行:
print '=== before: ' + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000)
DoDebugInfo(inputs)
print '=== after: ' + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000)
输出是:
=== before: 71598.08
=== after: 170237.952
=== before: 170237.952
=== after: 255696.896
=== before: 255696.896
=== after: 341409.792
如您所见,在调用之前,程序有内存占用,在调用之后它会增加,但在下一次调用之前保持稳定。
这是为什么?既然DoDebugInfo(inputs) 是一个什么都不返回的函数,那么一些变量怎么会留在内存中呢?是否需要在函数结束时清除所有变量?
编辑:
DoDebugInfo 导入此函数:
def plot_line(x,y,kind,lab_x,lab_y,filename):
fig = plt.figure(figsize=(11,6),dpi=300)
ax = fig.add_subplot(111)
ax.grid(True,which='both')
#print 'plotting'
if type(x[0]) is datetime.datetime:
#print 'datetime detected'
ax.plot_date(matplotlib.dates.date2num(x),y,kind)
ax.fmt_xdata = DateFormatter('%H')
ax.autoscale_view()
fig.autofmt_xdate()
else:
#print 'no datetime'
ax.plot(x,y,kind)
xlabel = ax.set_xlabel(lab_x)
ax.set_ylabel(lab_y)
fig.savefig(filename,bbox_extra_artists=[xlabel], bbox_inches='tight')
def plot_hist(x,Nbins,lab_x,lab_y,filename):
fig = plt.figure(figsize=(11,6),dpi=300)
ax = fig.add_subplot(111)
ax.grid(True,which='both')
ax.hist(x,Nbins)
xlabel = ax.set_xlabel(lab_x)
ax.set_ylabel(lab_y)
fig.savefig(filename,bbox_extra_artists=[xlabel], bbox_inches='tight')
并使用以下方式将 10 个图形绘制到磁盘上:
plot_line(index,alt,'-','Drive Index','Altitude in m',output_dir + 'name.png')
如果我注释使用plot_line 的行,问题不会发生,因此泄漏应该在这行代码上。
谢谢
【问题讨论】:
-
向我们展示您的
DoDebugInfo功能。 -
一个什么都不返回的函数仍然可以改变全局变量,或者使用一个在调用之间没有清理的可变参数。
-
@eumiro 我已经缩小了泄漏的范围,请看看我在
DoDebugInfo中使用的函数。这是某处的泄漏。谢谢 -
@MartijnPieters 该函数不会改变全局变量......我不知道什么是可变参数,但我会检查它。谢谢
-
Martijn 指的是mutable default argument gotcha。
标签: python memory-leaks profiler