Django: загруженные файлы не собираются с мусором, что вызывает проблемы с памятью

У меня есть представление Django, которое обрабатывает загруженные файлы, а когда оно вызывается многократно, мы всегда сталкиваемся с ошибками памяти. (Мы на Heroku, поэтому мы получаем 512 Мб памяти на каждый веб-дино).

Ошибки над памятью показывают, что каждый вызов увеличивает использование памяти по размеру файла, а использование памяти никогда не возвращается. Я думаю, что сервер считывает изображение в память, чтобы сохранить его в модели 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) 

Согласно документации Django, она поставляется с двумя обработчиками загрузки файлов. Обработчики файлов памяти и временных файлов ( ссылка на документы)

Если вы настроите параметры FILE_UPLOAD_HANDLERS , чтобы включить только «django.core.files.uploadhandler.TemporaryFileUploadHandler», он никогда не должен сохранять файл в памяти и технически никогда не вызывать проблем с памятью, с которыми вы сталкиваетесь в данный момент.

Другой вариант – установить FILE_UPLOAD_MAX_MEMORY_SIZE на небольшую сумму, которая заставит загрузку перейти непосредственно на диск.