【发布时间】:2014-03-21 09:10:35
【问题描述】:
在我正在开发的应用程序中,我使用multiprocessing.BaseManager 与主进程并行执行一些繁重而复杂的计算。我使用 Manager 而不是 Pool,因为这些计算是作为 class 实现的,并且只需要偶尔执行一次。
每次我在管理器中创建一个计算类的新实例时,调用它的方法,取回结果,然后删除该实例并在管理器中调用 gc.collect()。
这是一个演示情况的伪代码:
import gc
from multiprocessing.managers import BaseManager
class MyComputer(object):
def compute(self, args):
#several steps of computations
return huge_list
class MyManager(BaseManager): pass
MyManager.register('MyComputer', MyComputer)
MyManager.register('gc_collect', gc.collect)
if __name__ == '__main__':
manager = MyManager()
manager.start()
#obtain args_list from the configuration file
many_results = []
for args in args_list:
comp = manager.MyComputer()
many_results.append(comp.compute(args))
del comp
manager.gc_collect()
#do somthing with many_results
计算结果很大(200Mb-600Mb)。问题是:根据top,管理器进程使用的常驻内存在计算后显着增长(从 50Mb 增加到 1Gb)。如果在所有计算中使用单个 comp 对象或不调用 manager.gc_collect(),它会增长得更快。所以我猜这个对象确实被删除了并且垃圾收集器工作了,但仍然留下了一些东西。
这是 Manager 进程在五轮计算期间使用的驻留内存图:http://i.imgur.com/BY6KuXD.png
我的问题是:
- 我是否需要在 MyComputer 实现中搜索内存泄漏,或者这只是 python 内存管理系统的一个功能?
- 如果后者为真,是否有任何方法可以强制管理器进程将其“释放”的内存返回给操作系统?
【问题讨论】:
-
如果在主进程中进行计算(完全不涉及多处理)会有什么不同吗?
-
不。第一次执行计算时,进程使用的常驻内存有所增长,但在每次后续迭代结束时它保持不变。所以
del results; del comp; gc.collect()释放迭代期间分配的所有内存。 -
我的错误。我当然的意思是“是的,它是不同的”
标签: python python-2.7 memory-leaks multiprocessing