使用multiprocessing.Pool甚至在close()之后泄漏内存

时间:2012-01-08 12:03:00

标签: python xml memory-leaks multiprocessing

我在Python脚本中加载12个XML文件(每个30-80MB):

import xml.etree.ElementTree as ET
files = ['1.xml', '2.xml', ..., '11.xml', '12.xml']
trees = [ET.parse(f) for f in files]

这需要大约50秒才能运行。我将运行它几次,所以我想我会尝试使用多处理加速它:

import multiprocessing    
trees = [None] * len(files)

def _parse_(i):
    return (i, ET.parse(files[i]))

def _save_((i, tree)):
    trees[i] = tree

def concurrent_parse():
    pool = multiprocessing.Pool()
    for i in range(len(files)):
        pool.apply_async(func=_parse_, args=(i,), callback=_save_)
    pool.close()
    pool.join()

现在运行时间为30秒,这是一个很好的改进。但是,我从shell运行所有这些,然后以交互方式处理数据。在第一个非并发版本完成后,Python的内存使用率为1.73GB。在并发之后,内存使用量为2.57GB。

我是使用多处理的新手,所以如果我错过了一些基本的东西,请原谅我。但是在使用Pool之后丢失内存的所有其他问题都指向我正在调用close()的失败。

PS - 如果这是加载12个XML文件的一种非常愚蠢的方式,请随意这么说。

1 个答案:

答案 0 :(得分:2)

我不确定这实际上是一个漏洞,并行实现需要更多内存来同时保存所有文件。然后python可能正在删除对象,但没有将内存返回到OS,这看起来像python使用的内存比现有对象需要的内存多。
那么如果多次运行concurrent_parse()会发生什么?如果内存使用量是恒定的,则不是泄漏。如果每次运行后内存都会上升,那么这是一个问题,您可能需要查看此线程以获取有关跟踪泄漏的信息 - Python memory leaks