gpt4 book ai didi

python - 使用 Python 多处理的高内存使用率

转载 作者:IT老高 更新时间:2023-10-28 21:49:17 26 4
gpt4 key购买 nike

我看过几篇关于使用 Python 多处理模块的内存使用的帖子。然而,这些问题似乎并没有回答我在这里遇到的问题。我发布我的分析,希望有人可以帮助我。

问题

我正在使用多处理并行执行任务,我注意到工作进程的内存消耗无限增长。我有一个小的独立示例,应该可以复制我注意到的内容。

import multiprocessing as mp
import time

def calculate(num):
l = [num*num for num in range(num)]
s = sum(l)
del l # delete lists as an option
return s

if __name__ == "__main__":
pool = mp.Pool(processes=2)
time.sleep(5)
print "launching calculation"
num_tasks = 1000
tasks = [pool.apply_async(calculate,(i,)) for i in range(num_tasks)]
for f in tasks:
print f.get(5)
print "calculation finished"
time.sleep(10)
print "closing pool"
pool.close()
print "closed pool"
print "joining pool"
pool.join()
print "joined pool"
time.sleep(5)

系统

我正在运行 Windows,我使用任务管理器来监控内存使用情况。我正在运行 Python 2.7.6。

观察

我总结了下面 2 个工作进程的内存消耗。

+---------------+----------------------+----------------------+
| num_tasks | memory with del | memory without del |
| | proc_1 | proc_2 | proc_1 | proc_2 |
+---------------+----------------------+----------------------+
| 1000 | 4884 | 4694 | 4892 | 4952 |
| 5000 | 5588 | 5596 | 6140 | 6268 |
| 10000 | 6528 | 6580 | 6640 | 6644 |
+---------------+----------------------+----------------------+

在上表中,我尝试更改任务数并观察在所有计算结束时以及在 join-ing pool 之前消耗的内存。 'del' 和 'without del' 选项分别是我是否取消注释或注释 calculate(num) 函数内的 del l 行。计算前内存消耗在4400左右。

  1. 看起来手动清除列表会降低工作进程的内存使用量。我认为垃圾收集器会处理这个问题。有没有办法强制垃圾回收?
  2. 令人费解的是,随着任务数量的增加,两种情况下的内存使用量都在不断增长。有没有办法限制内存使用?

我有一个基于此示例的流程,旨在长期运行。我观察到这个工作进程在通宵运行后占用了大量内存(~4GB)。做一个 join 来释放内存不是一种选择,我试图找出一种没有 join-ing 的方法。

这似乎有点神秘。有没有人遇到过类似的事情?我该如何解决这个问题?

最佳答案

我做了很多研究,但找不到解决问题本身的解决方案。但是有一个不错的解决方法可以以很小的成本防止内存爆裂,尤其是在服务器端长时间运行的代码上。

解决方案本质上是在完成固定数量的任务后重新启动单个工作进程。 python 中的 Pool 类将 maxtasksperchild 作为参数。您可以指定 maxtasksperchild=1000 从而限制在每个子进程上运行 1000 个任务。达到 maxtasksperchild 数字后,池会刷新其子进程。为最大任务使用一个谨慎的数字,可以平衡消耗的最大内存与与重新启动后端进程相关的启动成本。 Pool 构造如下:

pool = mp.Pool(processes=2,maxtasksperchild=1000)

我将我的完整解决方案放在这里,以便对其他人有用!

import multiprocessing as mp
import time

def calculate(num):
l = [num*num for num in range(num)]
s = sum(l)
del l # delete lists as an option
return s

if __name__ == "__main__":

# fix is in the following line #
pool = mp.Pool(processes=2,maxtasksperchild=1000)

time.sleep(5)
print "launching calculation"
num_tasks = 1000
tasks = [pool.apply_async(calculate,(i,)) for i in range(num_tasks)]
for f in tasks:
print f.get(5)
print "calculation finished"
time.sleep(10)
print "closing pool"
pool.close()
print "closed pool"
print "joining pool"
pool.join()
print "joined pool"
time.sleep(5)

关于python - 使用 Python 多处理的高内存使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21485319/

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