2012-08-09 21 views
5

我有一個處理上傳文件的Django視圖,當它被重複調用時,我們總會遇到內存錯誤。 (我們在Heroku上,所以我們每個網頁dyno獲得512mb的內存)。Django:上傳的文件沒有被垃圾收集,導致內存問題

內存過量錯誤表明每次調用都會增加內存使用量,但內存使用量永遠不會回落。我認爲服務器將圖像讀入內存以將其保存到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) 
+0

這是什麼'image_meta_task.delay'? – 2012-08-09 18:45:15

+0

這是一個異步芹菜任務,它在獨立的服務器(不是我的網絡服務器)上啓動,將圖像處理爲標準大小並保存它們。 – 2012-08-09 18:47:15

+0

如果這是一個簡化版本,那意味着如果你放棄了'image_meta_task.delay'你沒有內存問題?另外,你在哪裏存儲文件?你能發佈settings.py存儲設置和'NewBusinessImage'嗎? – danihp 2012-08-09 18:56:49

回答

0

根據Django文檔,它帶有2個文件上傳處理程序。在內存和臨時文件處理程序(Link to docs)

如果配置設置FILE_UPLOAD_HANDLERS設置爲僅包括「django.core.files.uploadhandler.TemporaryFileUploadHandler」它不應該將文件保存到內存和技術上不會引起內存問題,你」重新此刻面對的問題。

另一種選擇是將FILE_UPLOAD_MAX_MEMORY_SIZE設置爲較小的量會導致上傳直接進入磁盤。