【发布时间】:2017-04-04 14:40:13
【问题描述】:
在运行 Django 应用程序(使用 gunicorn)时,我在 Heroku 上遇到内存问题。
我有以下代码,它获取用户上传的图像,删除所有 EXIF 数据,并返回准备好上传到 S3 的图像。这既可用作表单数据清理器,也可用于将 base64 数据读入内存。
def sanitise_image(img): # img is InMemoryUploadedFile
try:
image = Image.open(img)
except IOError:
return None
# Move all pixel data into a new PIL image
data = list(image.getdata())
image_without_exif = Image.new(image.mode, image.size)
image_without_exif.putdata(data)
# Create new file with image_without_exif instead of input image.
thumb_io = StringIO.StringIO()
image_without_exif.save(thumb_io, format=image.format)
io_len = thumb_io.len
thumb_file = InMemoryUploadedFile(thumb_io, None, strip_tags(img.name), img.content_type,
io_len, None)
# DEL AND CLOSE EVERYTHING
thumb_file.seek(0)
img.close()
del img
thumb_io.close()
image_without_exif.close()
del image_without_exif
image.close()
del image
return thumb_file
我基本上采用 InMemoryUploadedFile 并返回一个仅包含像素数据的新文件。
del 和 closes 可能是多余的,但它们代表了我尝试修复 Heroku 内存使用量不断增长并且每次此函数终止时都不会释放的情况,即使是过夜:
使用 Guppy 在 localhost 上运行它并按照教程进行操作,堆中没有剩余的 InMemoryUploadedFiles 或 StringIOs 或 PIL Image,这让我感到困惑。
我怀疑 Python 不会将内存释放回操作系统,因为我在 SO 上的多个线程中读过。有没有人玩过InMemoryUploadedFile,可以给我解释一下为什么这个内存没有被释放?
如果我不执行此清理,则不会出现此问题。
非常感谢!
【问题讨论】:
标签: python django memory heroku