由于数据的不断收集,我编写了一个需要一次运行多天的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
除了通用的python编码之外,对程序的主要更改是添加了一个多处理队列。这是我第一次使用此功能,所以我不确定这是否可能是问题的原因。我的程序中Queue的目的是能够在并行进程中进行动态更改。队列在主程序中启动,并在并行过程中持续受到监视。我在并行过程中如何执行此操作的简化版本如下('q'是队列):
while(1):
if q.empty():
None
else:
fr = q.get()
# Additional code
time.sleep(1)
对'q'的动态更改不会经常发生,所以大部分时间q.empty()都是正确的,但是一旦做出更改,循环就会准备就绪。我的问题是,一次运行此代码多个小时导致内存最终运行低?由于'while'循环很短并且基本上没有停止运行,我认为这可能是一个问题。如果这可能是问题的原因,那么有没有人对如何改进代码提出任何建议,以便不会调用内存杀手?
非常感谢你。
答案 0 :(得分:4)
以你描述的方式耗尽内存的唯一方法是随着时间的推移你使用越来越多的内存。这里的循环不演示了这种行为,所以它不能(单独)对任何内存错误负责。运行紧密的无限循环可以烧掉许多不必要的处理器周期,但除非它将数据存储到其他地方,否则它本身不会导致MemoryError
。
你的代码中的其他地方可能存在一些你不想要的变量。这称为内存泄漏,您可以使用memory profiler来查找此类泄漏的来源。
一些可能的嫌疑人是用于提高性能的缓存方法,或者从不留下范围的变量列表。也许您的多处理队列持有对早期数据对象的引用,或者一旦插入项目就永远不会从队列中删除它们? (如果您使用的是内置queue.Queue
,那么根据您显示的代码,后一种情况不太可能,但一切皆有可能。)
答案 1 :(得分:0)