6

アップロードされたファイルを処理する Django ビューがあり、それが繰り返し呼び出されると、常にオーバー メモリ エラーが発生します。(Heroku を使用しているため、Web dyno ごとに 512 MB のメモリが得られます)。

オーバー メモリ エラーは、呼び出しごとにメモリ使用量がファイルのサイズだけ増加し、メモリ使用量が元に戻らないことを示しています。サーバーはイメージをメモリに読み取って Django モデルに保存すると思いますが、完了してもメモリを解放することはありません。

関数が戻った後も持続する画像への参照が必要であり、画像がガベージコレクションされるのを防いでいると思います。しかし、それが何であるかは考えられません。

これは、同じ問題があることを確認するためにテストしたコードの簡略化されたバージョンです。

def simplified_add_image(request, biz_id):
    if request.is_ajax():
        # the file is stored raw in the request
        newBI = NewBusinessImage(business_id=biz_id, name=request.GET.get("name"), primary_image=True)
        newBI.id = uuid.uuid4()
        newBI.save()
        uniquename = biz_id + ".." + get_a_uuid() + ".jpg"

        newBI.original_image.save(uniquename, ContentFile(request.read()))

        # this starts a series of tasks to process the image into various sizes.
        # don't think it's the problem because it runs on a separate server, and the
        # web server is the one that goes over memory
        tasks.image_meta_task.delay(uniquename, newBI.id)

        return StockJSONResponse(request, {
            "success" : True,
        })

助けていただければ幸いです。どうもありがとう!

粘土

以下は、コメントで要求された追加情報です。

ファイルを AmazonS3 に保存しています。

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
STATIC_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME
from S3 import CallingFormat
AWS_CALLING_FORMAT = CallingFormat.SUBDOMAIN

そして、ここに NewBusinessImage モデルがあります

class NewBusinessImage(models.Model):
    id = UUIDField(auto=True,primary_key=True,version=4, default=uuid.uuid4())
    business = models.ForeignKey('Business')
    name = models.CharField(max_length=100)
    original_image = models.ImageField(upload_to='photos/originals/')
    thumbnail = models.ImageField(upload_to='photos/thumbnails/')
    display_image = models.ImageField(upload_to='photos/displays/')
    enlarged_image = models.ImageField(upload_to='photos/enlarged/')
    num_views = models.PositiveIntegerField(editable=False, default=0)
    primary_image = models.BooleanField(default=False)
4

1 に答える 1