2012-02-28 5 views
2

최근 WebFaction에서 Django 프로젝트 및 메모리 사용 문제가 발생했습니다.Django의 이미지를 자르면 상당한 메모리 증가가 발생합니다.

69720 4-20:20:22 13486 
30404 4-20:20:22 13487 

당신이 볼 수 있듯이 : 프로세스 중 하나가 실질적으로 증가 실행되는보기 후

30396 4-20:20:00 13486 
30404 4-20:20:00 13487 

: 여기

는 webfaction에이 프로젝트를 위해 메모리에서 실행중인 두 프로세스입니다 메모리 사용량이 두 배 이상 증가한 첫 번째 프로세스! 이 기능이 자주 사용되기 때문에 나는 무엇이 일어나고 있는지 알아낼 필요가있다. 나는 그것을 다음의보기로 좁혔다 고 믿는다 (그것은 이미지를 업로드하고, 세부 사항을 추가하고, 작은 그림을 자르는 3 단계 과정이다).

다음은 아래보기입니다. 사진 객체를 가져 와서 파일에서 이미지를로드하고 사용자가 제출 한 좌표 상자를 가져온 다음 200,200 크기의 이미지를 만듭니다. 이 새로 생성 된 이미지는 파일 이름에 .thumbnail이있는 디스크에 다시 쓰여지고 사진 객체가 저장됩니다.

@login_required 
def upload3(request, photo_pk): 
    photo = get_object_or_404(Photo, pk=photo_pk, user=request.user) 
    if request.method == "POST": 
     form = upload3Form(request.POST) 
     if form.is_valid(): 
      im = Image.open(photo.image.path) 
      try: 
       box =(form.cleaned_data['x1'],form.cleaned_data['y1'],form.cleaned_data['x2'],form.cleaned_data['y2']) 
      except: 
       box = ('0','0','1000','1000') 
      cropped = im.crop(box) 
      cropped.thumbnail((200,200),Image.ANTIALIAS) 
      result = os.path.splitext(photo.image.path) 
      cropped.save(result[0] + '.thumbnail' + result[1]) 
      photo.status = 3 
      photo.save() 

내가 잘못했을 수있는 아이디어는 크게 감사하겠습니다.

Update 1 : 테스트에 사용 된 이미지는 모두 JPEG이며 크기는 약 3600 x 2700이며 이미지 당 약 2MB입니다.

+0

뷰에서 메모리 사용이 증가하는 작업을 좁혔습니까? 뷰를 여러 번 호출하면 어떻게됩니까? –

+0

아니요, 라이브 서버 (예 : pdb)에서 많은 디버깅 작업을 수행 할 수 없기 때문에 제가하지 못했습니다. 보기가 호출 될 때마다 발생하지는 않지만 대부분의 경우에 발생하는 것처럼 보입니다. (몇 주 전에 이미지 몇 장을 업로드 한 후 한 프로세스에서 메모리 사용량이 112MB 이상이었습니다). – Fernker

+0

질문을 일반적인 이미지 크기 및 형식으로 업데이트 하시겠습니까? –

답변

0

많은 파기 및 막 다른 골목에서 나는 아무 곳이나 제안하지 않은 것을 시도하고 효과를 보았습니다.

PIL에 사용 된 이미지 개체가 포함 된 각 개체에서 개체를 삭제해야했습니다. 따라서 예를 들면 다음과 같습니다.

im = Image.open(photo.image.path) 
try: 
    box =(form.cleaned_data['x1'],form.cleaned_data['y1'],form.cleaned_data['x2'],form.cleaned_data['y2']) 
except: 
    box = ('0','0','1000','1000') 
cropped = im.crop(box) 
newimage = cropped.resize((form.cleaned_data['dw'],form.cleaned_data['dh']),Image.ANTIALIAS) 
del im 
del cropped 

개체를 다 끝냈 으면 해당 항목을 del이라고 부릅니다. 문제가 해결 된 것 같습니다. 나는 더 이상 기억력을 상실하지 않으며 행복하지도 못합니다.

+0

자신의 질문에 대답하고 대답에서 동의를 되 찾는 대신 발견 한 해결책으로 질문을 업데이트하는 것이 훨씬 더 좋을 것입니다. –

+0

나는 내 것이 더 완전한 답이라고 생각하고 사람들이 질문에 올 때 원래 질문에 대한 업데이트보다 녹색 체크 박스를 더 많이 본다. 너에게 현상금을 줬어. – Fernker

2

2M 숫자는 압축 된 JPEG 이미지를위한 것이지만 압축하지 않은 상태에서 3600 x 2700 truecolor는 발생하는 메모리 사용량에 거의 근접한 약 38M (픽셀 당 4By당 9,720,000 픽셀)입니다.

이것은 PIL의 알려진 문제점이며 40000x40000 픽셀의 검은 색 그림을 png로 보내 픽셀 폭탄을 생성 할 수 있습니다. 로드하기 전에 항상 해상도를 확인하십시오 (또는 OutOfMemory를 처리하는 try/except 블록으로 코드를 보호하십시오). 청크로 이미지 청크를 처리하기 위해 im.tile 속성을 사용하면 더 적은 메모리 사용량을 줄 수 있는지 확인하십시오.

  • GDAL (지리 : 큰 이미지를 처리 ​​할 때 더 나은 핸들 메모리에 있다고합니다

    일부 대안 :

    가치가 검사 할 수 있음 데이터 추상화 라이브러리)

  • OIIO (OpenImageIO)
  • Mahotas (NumPy와)

[업데이트]

당신이 메모리에서 개체를 해제 PIL있는 방법이 있는지 알고 있습니까? 이론적으로이 뷰는 내가하는 것처럼 작동해야하지만 이미지를 더 잘 처리해야하므로이 뷰에 가장 적합 할 것입니다.메모리를 방지하기 위해

  • 는 큰 이미지를 감지하고 (unfortunatelly 낮은 수준에서 작동) 덩어리가 im.tile를 사용하는 대신 im.crop에서 그들을 처리하기 위해 시도 할 수 있습니다 스파이크.
  • 가벼운 스파이크를 얻기 위해 가능한 한 빨리 중간 이미지 개체를 삭제할 수 있습니다 (gc module을 사용하면 가비지 수집기를 강제로 정리할 수 있음).
+0

아, 사진 압축에 대해 생각 해보지 않았을 것입니다. 나는 당신이 제안한 것에 대해 더 많이 살펴보기 시작했고, 그들이 효과가 있는지 보게 될 것입니다. 메모리에서 객체를 해제하는 PIL의 방법이 있는지 알고 있습니까? 이론적으로이 뷰는 내가하는 것처럼 작동해야하지만 이미지를 더 잘 처리해야하므로이 뷰에 가장 적합 할 것입니다. 감사. – Fernker

+0

죄송합니다. 귀하가 귀하의 답변을 업데이트 한 것을 알지 못했습니다. 메모리 스파이크의 원인에 대한 통찰력을 제공 할 때 답변 해 주셔서 감사합니다. (내 질문이 무엇인지). 필자는 WebFaction과 대화하여 몇 시간 동안의 작업이 필요하지 않은 해결 방법에 대한 아이디어를 얻었으므로 아이디어가 있는지 확인하려고합니다. – Fernker