为运行多处理队列的 python 脚本激活了内存不足杀手?

rms*_*987 4 python queue out-of-memory multiprocessing kill-process

由于不断收集数据,我编写了一个需要一次运行多天的python程序。以前我一次运行这个程序几个月都没有问题。我最近对该程序进行了一些更新,现在大约 12 个小时后,我得到了可怕的记忆杀手。'dmesg' 输出如下:

[9084334.914808] Out of memory: Kill process 2276 (python2.7) score 698 or sacrifice child
[9084334.914811] Killed process 2276 (python2.7) total-vm:13279000kB, anon-rss:4838164kB, file-rss:8kB
Run Code Online (Sandbox Code Playgroud)

除了一般的 Python 编码外,对程序所做的主要更改是添加了多处理队列。这是我第一次使用此功能,所以我不确定这是否可能是问题的原因。我的程序中队列的目的是能够在并行进程中进行动态更改。队列在主程序中启动,并在并行进程中不断被监视。我如何在并行过程中执行此操作的简化版本如下(“q”是队列):

while(1):

    if q.empty():
        None

    else:
        fr = q.get()
        # Additional code

    time.sleep(1)
Run Code Online (Sandbox Code Playgroud)

'q' 的动态更改不会经常发生,因此大部分时间 q.empty() 将是 true,但是一旦进行更改,循环就会准备就绪。我的问题是,一次运行此代码多个小时会导致内存最终耗尽吗?由于“while”循环非常短并且基本上不停地运行,我认为这可能是一个问题。如果这可能是问题的原因,是否有人对如何改进代码以便不调用内存不足杀手有任何建议?

非常感谢。

Hen*_*ter 5

以您描述的方式耗尽内存的唯一方法是随着时间的推移使用越来越多的内存。此处的循环演示此行为,因此它不能(仅)对任何内存错误负责。运行一个紧密的无限循环可能会消耗大量不必要的处理器周期,但它MemoryError本身不会导致 a ,除非它将数据存储到其他地方。

很可能在您的代码中的其他地方,您保留了一些您不打算使用的变量。这称为内存泄漏,您可以使用内存分析器查找此类泄漏的来源。

一些可能的嫌疑人是用于提高性能的缓存方法,或者永远不会离开作用域的变量列表。也许您的多处理队列保留了对早期数据对象的引用,或者项目一旦插入就永远不会从队列中删除?(鉴于您使用的是 builtin 所显示的代码,后一种情况不太可能发生queue.Queue,但一切皆有可能)。

  • @Stefano 这怎么不是答案?`“我的问题是,一次运行此代码多个小时会导致内存最终耗尽吗?”` 答案是否定的,给定的代码不会导致程序内存不足。 (3认同)