1

私は簡単なセットアップをしています:

Producer はカメラから一連の画像を読み取り、numpy.row_stack() を使用してそれらを連結します。生成された配列は Queue.Queue に入れられます。

Consumer は Queue.get() を使用して常にデータを待ち、データを受け取るとすぐに画像をファイルに保存します。なんらかの理由で、明日がないようにプロセスがメモリをリークします。画像をスレッド キューに入れなければ、リークは発生しません。どうやら漏れているのはキューではなく、画像保存機能の何かです。具体的には、一時ファイルの作成部分にあります。実装は次のとおりです。

def _createTmpFile(self, image):
    filename = '/tmp/imgTemp.gray'
    with open(filename, 'wb') as fp: 
        scaled  = image * 16
        big     = numpy.asmatrix(scaled, dtype='>i2')
        fp.write(big.tostring())
    return filename

def _saveImage(self, filename, image):
    tmpFile = self._createTmpFile(image)
    try:
        # Call a blocking sub process command to convert the image:
        command = ('convert -size %dx%d -depth 16 -endian MSB' % ( image.shape[1], image.shape[0])).split(' ')
        command += [tmpFile, '/tmp/' + os.path.basename(filename)]
        log.debug("command being called: %s" % str(command))
        subprocess.call(command)
        os.unlink(tmpFile)
        log.info("Image %s is saved." % filename)
    except Exception as e:
        log.exception()
        log.warning("Failed to save image %s" % filename)

メモリリークの原因となる、特に目立ったものは何もありません。何か案は?

更新: 徹底的な分析の後、問題は非常に単純であることが判明しました。プロデューサーは、コンシューマーが保存できる速度よりもはるかに速い速度でイメージを作成していたため、キューがいっぱいになりました。画像のリクエストをキャンセルすると、キューを空にしますが、GC が多数の画像を取得するのに十分な速さではなかったようで、メモリを詰まらせていました。

4

1 に答える 1

0

subprocess.call() が理由です。そこに待機コマンドなどを入れるか、新しい端末などにコマンドを入れて、kwarg を使用する必要があります。それ以外の場合は呼び出しを開始し、後でキュー内で同様のことを行うため (コマンドラインの使用はサブプロセスではトリッキーです)

subprocess.call の代わりに shell=True を指定した check_call() が機能するはずだと思いますが、それについても完全にはわかりません。私はかつて同様の問題を抱えていましたが、それは解決したと思います

もう 1 つの理由は、キューで createTmpFile を複数回呼び出すと、同じ一時イメージに書き込むため、複数のイメージが互いに上書きされるなどです。それは私が推測するメモリリークを引き起こす可能性があります

于 2013-07-16T08:17:50.060 に答える