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

Python第二次执行多进程代码块时内存占用大幅升高是什么原因?

Python多进程二次调用内存暴涨问题解决方案

核心原因

  • Linux环境下Python multiprocessing 默认使用fork模式创建子进程:创建第二个进程池时,父进程已经加载了总大小约20G的id_map和all_data数据,fork生成的子进程会继承父进程全部内存空间。虽然系统默认采用写时复制机制,但Python对象的引用计数会被自动修改,触发写时复制逻辑,原本共享的内存会变成每个子进程的私有拷贝,这是每个子进程启动就占用17G左右内存的核心原因。
  • 大对象重复传参:你在starmap中通过repeat(id_map)给每个任务重复传递大字典,哪怕子进程已经通过fork继承了该对象,额外的序列化、反序列化操作也会产生额外内存拷贝,加剧内存占用。
  • 进程池资源未及时释放:第一个create_id中的进程池使用完成后没有调用close()、join()方法回收资源,残留的内存占用会叠加到后续进程的开销中。
  • pandas中间对象延迟回收:process_data中的replace、drop_duplicates等pandas操作会生成数据副本,Python GC不会立刻回收这部分内存,长期运行会产生内存碎片,导致内存占用逐步上涨。

解决方案

  1. 更换进程启动模式为spawn,在程序入口处添加如下代码:
import multiprocessing
multiprocessing.set_start_method('spawn')

spawn模式创建的子进程只会复制必要的执行逻辑,不会继承父进程的全部内存空间,可直接避免fork模式带来的大量冗余内存拷贝。注意spawn模式下不会自动继承父进程的全局变量,需要明确传递需要的参数。

  1. 优化大对象传递逻辑:不要将id_map作为每个任务的参数重复传递,可将id_map存入multiprocessing.Manager生成的共享字典中,所有子进程直接访问共享对象,避免每个子进程持有一份完整副本。

  2. 及时回收资源:

  • 第一个进程池使用完成后立刻调用close()和join()释放资源
  • 不再使用的临时变量手动执行del删除,随后调用gc.collect()强制回收内存,比如create_id执行完成后如果不需要保留原始的all_data副本,可直接删除触发回收。
  • process_data中处理完成的node_df、rel_df、relations等临时对象,用完立刻手动删除,减少内存驻留。
  1. 调整进程池调用方式:将starmap替换为imap/imap_unordered,减少任务队列中缓存的待处理任务数量,避免大量待传递的参数对象提前占用内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:27:05