Python popen耗尽大量输出的内存

时间:2012-07-17 14:17:18

标签: python

我正在使用subprocess.popen()函数来运行一个读取&的外部工具。将大量数据(> GB)写入stdout。但是,我发现内核在内存不足时会杀死python进程:

Out of memory: Kill process 8221 (python) score 971 or sacrifice child
Killed process 8221 (python) total-vm:8532708kB, anon-rss:3703912kB, file-rss:48kB

因为我知道我正在处理大量数据,所以我设置了popen来将stdout和stderr写入文件,所以我没有使用管道。我的代码看起来像这样:

errorFile = open(errorFilePath, "w")
outFile = open(outFilePath, "w")
#Use Popen to run the command
try:                
    procExecCommand = subprocess.Popen(commandToExecute, shell=False, stderr=errorFile, stdout=outFile)
    exitCode = procExecCommand.wait()

except Exception, e:
    #Write exception to error log       
    errorFile.write(str(e))     

errorFile.close()
outFile.close()        

我尝试将shell参数更改为True并设置bufsize参数= -1也没有运气。

我已经分析了运行此脚本的内存并通过bash,我发现通过Python运行时内存使用率大大高于bash。

我不确定Python正在做什么来消耗比仅仅使用bash更多的内存,除非它有尝试将输出写入文件的东西? bash脚本只是将输出传递给文件。

我最初发现我的交换空间非常低,所以我增加了它并且最初有所帮助,但随着数据量的增长,我又开始耗尽内存。

因此,我可以做些什么来尝试更好地处理这些数据量,或者只是建议使用大量交换空间来增加内存。那个或者抛弃Python一起。

系统详情:

  • Ubuntu 12.04
  • Python 2.7.3
  • 我正在运行的工具是来自samtools的mpileup。

2 个答案:

答案 0 :(得分:0)

问题可能是您正在使用{{1>}方法(如 procExecCommand.wait()),该方法尝试运行子流程以完成然后返回。试试this question中使用的方法,该方法使用例如进程句柄wait()。这样你就可以定期清空管道,写入文件,不应该有内存堆积。

答案 1 :(得分:0)

你的过程产生了什么样的输出,也许是线索。

警告:脚本不会终止,您必须将其终止。

此示例设置按预期工作。

import subprocess

fobj = open("/home/tst//output","w")

subprocess.Popen("/home/tst//whileone",stdout=fobj).wait()

而且还有人

#!/bin/bash

let i=1
while [ 1 ]
do
 echo "We are in iteration $i"
 let i=$i+1
 usleep 10000
done