垃圾收集python子进程
tl;dr:我有一些返回值巨大的任务,它们会消耗大量内存。我将它们提交给一个垃圾收集python子进程,python,concurrent.futures,Python,Concurrent.futures,tl;dr:我有一些返回值巨大的任务,它们会消耗大量内存。我将它们提交给一个并发的.futures.ProcessPoolExecutor。子进程保留内存,直到它们接收到新任务。如何强制子进程有效地进行垃圾收集 例子 在上面的示例中,我在子流程中创建一个大对象,然后处理结果。从这一点开始,我可以处理父进程中的内存,但是由ProcessPoolExecutor创建的子进程将无限期地保留分配给我的任务的内存 我试过的 老实说,我唯一能想到的就是提交一个虚拟任务: def donothing():
并发的.futures.ProcessPoolExecutor
。子进程保留内存,直到它们接收到新任务。如何强制子进程有效地进行垃圾收集
例子
在上面的示例中,我在子流程中创建一个大对象,然后处理结果。从这一点开始,我可以处理父进程中的内存,但是由ProcessPoolExecutor创建的子进程将无限期地保留分配给我的任务的内存
我试过的
老实说,我唯一能想到的就是提交一个虚拟任务:
def donothing():
pass
executor.submit(donothing)
这是可行的,但a)相当笨拙,更重要的是b)不可信,因为我无法保证将任务发送到哪个子进程,所以唯一简单的方法是发送一个洪水,以确保我关心的子进程获得副本
据我所知,工作进程一旦完成运行我的任务,就没有理由保留结果。如果我的父进程将返回的Future
分配给一个局部变量,那么在任务完成时,返回值将复制到父进程中的Future
,这意味着工人不再需要它。如果我的父进程没有这样做,那么返回值实际上会被丢弃
我是误解了什么,还是这只是子进程如何引用内存的一个不幸的怪癖?如果是这样,有更好的解决方法吗?您的虚拟任务方法是在不进行重大代码重构的情况下完成此任务的唯一方法(以避免返回巨大的值) 问题在于,工作进程正在处理,并且只有在新任务进入时才替换
r
在调用
\u sendback\u result
后,您可以合理地在上打开一个增强/错误请求,让工作人员显式地delr
;出于完全相同的原因,它已经为调用\u item
(发送给worker的打包函数和参数)执行此操作,以避免在资源的可用窗口之外保留资源,对已经返回且不再相关的结果执行同样的操作是有意义的。为什么不使用多处理共享列表呢?感谢@ShadowRanger,这是一个很好的答案,它不仅解释了问题,而且指出了在Python中解决问题的正确方向。认可的
def donothing():
pass
executor.submit(donothing)