问题
使用multiprocessing.Pool创建多进程时,每个进程占用内存不断攀升。
问题描述
原本每个子进程没有占用那么多内存:
第二次读取新一批数据,每个子进程都复制了之前的内存资源:
原因说明
实际上,multiprocessing.Process每启动一个进程,都会对当前进程内存进行一次拷贝。
因为multiprocessing有两种创建进程的方式:spawn和fork,在linux系统中的默认创建模式是fork,fork会把当前进程资源全部复制一份交给子进程。因此当需要不断重复:读写数据->多进程处理数据这一流程,会不断产生的新子进程复制之前的资源,导致进程占用内存越来越大。
因此平时推荐使用spawn方式创建多个进程,fork方式会产生孤儿进程和僵尸进程,需要手动回收资源。采用spawn方式初始化多进程创建,虽然spawn比fork要慢一些,但是能够节省内存、也更加安全。
解决方法
多进程创建方式是可以修改的:
multiprocessing.set_start_method('spawn') # default on WinOS or MacOSmultiprocessing.set_start_method('fork') # default on Linux (UnixOS)
由于多进程创建方式的初始化是在主进程刚开始就创建好的,因此你需要在主进程程序入口处
if __name__ =='__main__':做修改:
程序入口处修改多进程创建方式后,即使多进程处理的代码是从别处调用过来,也能够通过spawn方式创建进程。
另外,尝试过用concurrent库来替换,并不好用
使用python多进程concurrent.futures.ProcessPoolExecutor使用方法示例
来自 <python多进程concurrent.futures.ProcessPoolExecutor使用方法示例_processpoolexecutor()使用示例-CSDN博客>
参考资料:
在Python中优雅地用多进程:进程池 Pool、管道通信 Pipe、队列通信 Queue、共享内存 Manager Value-腾讯云开发者社区-腾讯云 (tencent.com)