python循环会迅速增加内存使用量

2024-10-02 06:24:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个运行循环的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)

输出为:

^{pr2}$

如您所见,在调用之前,程序有内存占用,在调用之后它会增加,但在下一次调用之前保持稳定。在

为什么会这样?既然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的行进行注释,问题不会发生,因此泄漏应该在这几行代码上。在

谢谢


Tags: 函数datetimeplotlinelabfigaxfilename
2条回答

尺寸会无限增长吗?很少有程序(或库)将堆返回给系统,即使不再使用,CPython(2.7.3)也不例外。通常的罪魁祸首是malloc,它将按需增加进程内存,并在free上将空间返回到其空闲列表中,但从不从系统中取消分配它已请求的内存。此示例代码有意获取内存,并显示进程使用是有界和有限的:

import resource

def maxrss(start, end, step=1):
    """allocate ever larger strings and show the process rss"""
    for exp in range(start, end, step):
        s = '0' * (2 ** exp)
        print '%5i: %sk' % (exp, 
            resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000)
    # s goes out of scope here and is freed by Python but not returned 
    # to the system

try:
    maxrss(1, 40, 5)
except MemoryError:
    print 'MemoryError'

maxrss(1, 30, 5)

其中输出(在我的机器上)部分是:

^{pr2}$

这表明解释器无法从系统中获取2**36字节的堆,但仍有“手头”的内存来填充以后的请求。正如脚本的最后一行所示,内存是供Python使用的,即使它当前没有使用它。在

问题在于有这么多的数字被创造出来,而且从来没有关闭过。不知怎么的,Python让它们都活了下来。在

我加了句台词

plt.close()

对我的绘图函数plot_lineplot_hist中的每一个,问题都解决了。在

相关问题 更多 >

    热门问题