gpt4 book ai didi

python - 多处理管理器进程不释放内存

转载 作者:太空宇宙 更新时间:2023-11-03 18:34:02 25 4
gpt4 key购买 nike

在我正在开发的应用程序中,我使用 multiprocessing.BaseManager 与主进程并行执行一些繁重且复杂的计算。我使用管理器而不是池,因为这些计算是作为实现的,并且只需要偶尔执行一次。

每次我在管理器中创建计算类的新实例时,调用其方法,返回结果,然后删除该实例并在管理器中调用 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 进程在五轮计算期间使用的常驻内存的图:/image/38tdo.png

我的问题是:

  1. 我是否需要在 MyComputer 实现中搜索内存泄漏,或者这只是 python 内存管理系统的一个功能?
  2. 如果后者为真,是否有任何方法可以强制管理器进程将其“释放”的内存返回给操作系统?

最佳答案

经过一个多星期的研究,我正在回答我自己的问题:

  1. 所描述的内存使用情况确实是Python内存管理系统的一个功能,它不会释放分配给小对象的内存。因此,如果计算过程中产生的数据量很大,最好预先分配包含该数据的对象。 NumPy 数组是一种选择;也许还有内置数组。
  2. 不,没有办法做到这一点。更重要的是:据我所知,即使在 C 语言中, free() 调用也不一定会导致内存返回到操作系统。

调查的另一个重要结论:

请注意这些巨大的内存峰值 ( /image/38tdo.png )。它们比生成的任何结果 (~250Mb) 都要大得多。事实证明,这是因为它们在加工过程中经过了腌制和未腌制。酸洗是一个非常昂贵的过程;它的内存使用量与要腌制的对象的大小具有非线性相关性。因此,如果您(取消)pickle 一个约 10Mb 大的对象,它会使用约 12-13Mb,但(取消)pickle 约 250Mb 将使用 800-1000Mb!因此,为了pickle一个大对象(其中包括管道、队列、连接、架子等的任何使用),您需要以某种方式序列化该过程。

关于python - 多处理管理器进程不释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21907574/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com