0

Python サーバー アプリでメモリ リークが発生している理由を診断しようとしています。アプリは画像 URL のリクエストを受け取り、Vips を使用してサイズを変更し、画像を返します。リクエストのたびに、メモリ使用量は元の画像のサイズにほぼ比例して増加します。

from fapws import base
import fapws._evwsgi as evwsgi
from gi.repository import Vips
import urllib2
import hmac
import hashlib
import base64
import StringIO
from boto.s3.connection import S3Connection
from boto.s3.bucket import Bucket

def start():
    evwsgi.start('0.0.0.0', '80')
    evwsgi.set_base_module(base)

    def lfrThumbnail(environ, start_response):
        try:
            parameters = environ['PATH_INFO'].split('/')
            s3File = 'my s3 url' + parameters[0]
            width = float(parameters[1])
            height = float(parameters[2])
            hmacSignatureUser = parameters[3]

            hmacSignature = some hasing code...

            if not (hmacSignatureUser == hmacSignature):
                print hmacSignatureUser
                print hmacSignature
                print hmacSignatureUser == hmacSignature
                raise Exception

            bufferedImage = urllib2.urlopen(s3File).read()
            image = Vips.Image.new_from_buffer(bufferedImage, '')

            imageWidth = float(image.width)
            imageHeight = float(image.height)
            imageAspectRatio =  imageWidth / imageHeight
            if (width > imageWidth) or (height > imageHeight):
                image = image
            elif abs((imageAspectRatio / (width/height)) - 1) < 0.05:
                image = image.resize(width / imageWidth)
            else:
                scaleRatioWidth = width / imageWidth
                scaleRatioHeight = height / imageHeight
                maxScale = max(scaleRatioWidth, scaleRatioHeight)
                image = image.resize(maxScale)
                cropStartX = (image.width - width) / 2
                cropStartY = (image.height - height) / 2
                image = image.crop(cropStartX, cropStartY, width, height)

        except Exception, e:
            start_response('500 INTERNAL SERVER ERROR', [('Content-Type','text')])
            return ['Error generating thumbnail']

        start_response('200 OK', [
            ('Content-Type','image/jpeg'),
            ('Cache-Control: max-stale', '31536000')
        ])
        return [image.write_to_buffer('.jpg[Q=90]')]

    evwsgi.wsgi_cb(('/lfr/', lfrThumbnail))

    evwsgi.set_debug(0)
    evwsgi.run()

if __name__ == '__main__':
    start()

pimplerトラッカーである muppy を使用してみましたが、画像のオープン/クローズ操作後の各差分は、使用されているバイトが数バイトしかないことを示していました。

外部 C ライブラリがメモリ リークの原因でしょうか? もしそうなら、それをどのようにデバッグしますか。

関連するものがある場合は、docker コンテナー内で python サーバーを実行しています

4

1 に答える 1