subprocess.popen() 関数を使用して、大量のデータ (> GB) を標準出力に読み書きする外部ツールを実行しています。ただし、メモリが不足すると、カーネルが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
私は大量のデータを処理していることを知っているので、パイプを使用していないので、stdout と stderr をファイルに書き込むように popen をセットアップしました。私のコードは次のようになります。
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 でできることはありますか。それとも、十分なスワップ スペースを備えたより多くのメモリを推奨する場合にすぎませんか。それかPythonを完全に放棄します。
システムの詳細:
- Ubuntu 12.04
- パイソン 2.7.3
- 私が実行しているツールは、samtools の mpileup です。