2012-08-09 21 views
5

Tôi có chế độ xem Django xử lý các tệp đã tải lên và khi được gọi nhiều lần, chúng tôi luôn gặp phải lỗi bộ nhớ. (Chúng tôi đang ở trên Heroku, vì vậy chúng tôi nhận được 512MB bộ nhớ cho mỗi trang web dyno).Django: Các tệp đã tải lên không bị thu gom rác, gây ra vấn đề về bộ nhớ

Lỗi bộ nhớ thừa cho biết mỗi cuộc gọi tăng mức sử dụng bộ nhớ theo kích thước của tệp và mức sử dụng bộ nhớ không bao giờ quay trở lại. Tôi nghĩ rằng máy chủ đọc hình ảnh vào bộ nhớ để lưu nó vào một mô hình Django, nhưng sau đó không bao giờ phát hành bộ nhớ khi nó được thực hiện.

Tôi nghĩ rằng phải có một tham chiếu đến hình ảnh đó là sự bền bỉ sau khi hàm trả về, ngăn không cho hình ảnh bị thu gom rác. Nhưng tôi không thể nghĩ đó là cái gì.

Dưới đây là một phiên bản đơn giản của các mã, mà tôi thử nghiệm để chắc chắn rằng nó có cùng một vấn đề:

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, 
     }) 

tôi thực sự đánh giá cao sự giúp đỡ nào. Cảm ơn rất nhiều!

Clay

Sau đây là thông tin bổ sung được yêu cầu trong ý kiến:

Chúng tôi đang lưu trữ các file của chúng tôi trên 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 

Và đây là mô hình 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

này 'image_meta_task.delay' là gì? –

+0

đó là một nhiệm vụ cần tây không đồng bộ , khởi chạy trên một máy chủ riêng biệt (không phải máy chủ web của tôi), để xử lý hình ảnh thành kích thước chuẩn và lưu chúng. –

+0

Nếu đây là phiên bản được đơn giản hóa, điều đó có nghĩa là nếu bạn thả 'image_meta_task.delay', bạn không có vấn đề về bộ nhớ? Ngoài ra, bạn lưu trữ tệp ở đâu? Bạn có thể đăng settings.py cài đặt lưu trữ và 'NewBusinessImage'? – danihp

Trả lời

0

Theo tài liệu của Django, nó có 2 trình xử lý tải tệp lên. Bộ nhớ và tập tin tạm thời xử lý (Link to docs)

Nếu bạn cấu hình các thiết lập FILE_UPLOAD_HANDLERS thiết lập để chỉ bao gồm "django.core.files.uploadhandler.TemporaryFileUploadHandler" nó nên không bao giờ lưu các tập tin vào bộ nhớ và về mặt kỹ thuật không bao giờ gây ra các vấn đề bộ nhớ bạn' tái đối mặt vào lúc này.

một lựa chọn khác sẽ được thiết lập FILE_UPLOAD_MAX_MEMORY_SIZE đến một số lượng nhỏ mà sẽ làm cho tải lên để đi trực tiếp vào đĩa.

Các vấn đề liên quan