You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程处理大数组时的内存问题解决方案咨询

问题

我有10个长数组arr1, arr2, ..., arr10,每个数组需传入函数foo处理。每个arr是包含约1亿个浮点数的列表。我希望使用多进程实现,示例代码如下:

import multiprocessing as mp

def foo(arr):
    # ...调用外部模块处理arr...
    # 返回一个浮点数


myarrays = [arr1, ..., arr10]
with mp.Pool(8) as pool:
    result = pool.map(foo, ((arr,)  for arr in myarrays))

# 我不再需要myarrays了

for res in result:
    # ...后续处理...

我遇到的问题(可能有误)是:8个进程的内存占用量都很高,且foo调用完成后程序似乎出现挂起。请问有没有更优的处理方式?

优化方案
  • 减少进程间数据拷贝:Python多进程在Unix/Linux下默认用fork,会复制父进程的全部内存(包括所有10个数组),导致每个子进程都持有数组副本,内存暴增。可以改用numpy数组替代Python列表,借助multiprocessing.Array或numpy的共享内存机制传递数据,避免全量拷贝;也可以给mp.Pool设置maxtasksperchild=1,让每个进程处理完一个任务就销毁,防止内存累积。

  • 调整进程池大小:单个数组约800MB(1亿个浮点数,每个占8字节),8个进程同时运行会占用约6.4GB内存,远超很多机器的内存上限,触发频繁swap导致程序卡顿挂起。建议将进程池大小设置为和CPU核心数一致(比如4核设为4),甚至更低,避免内存过载。

  • 提前释放父进程内存:提交任务后立即删除myarrays并强制垃圾回收,减少父进程内存占用,避免和子进程争抢内存:

with mp.Pool(4) as pool:
    result = pool.map(foo, ((arr,) for arr in myarrays))
del myarrays
import gc
gc.collect()
  • 改用imap_unordered替代map:pool.map会等待所有任务完成才返回结果,若单个任务异常卡住会导致整个程序挂起。imap_unordered可以逐个返回已完成的任务结果,方便排查问题,同时内存占用更低,不会一次性加载所有输入数据。

  • 排查foo函数的内存泄漏:如果foo调用的外部模块未正确释放内存,会导致子进程内存持续增长。可以在foo末尾手动删除arr引用,或用tracemalloc工具排查内存使用情况。

内容的提问来源于stack exchange,提问作者theQman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:10:04