2012-07-24 4 views
2

메모리 부족 경고와 관련된 게시물을 많이 읽었지만 앱에서 충돌 문제를 해결할 수 없었습니다. 악기의 할당은 2-7MB 범위의 라이브 바이트를 보여줍니다. 7 또는 7.5MB를 넘지는 않지만 앱이 계속 충돌합니다.메모리 사용량이 매우 낮아 앱이 다운 됨

할당 및 활동 모니터가 다른 메모리 사용 값을 보여주는 링크를 읽었습니다. 앞서 지정된대로 Allocations는 최대 7-7.5MB를 표시하지만 Activity Monitor는 앱이 시작될 때 약 75MB 사용량을 표시하며 프로그램을 사용할 때 증가 및 감소합니다. 그것은 110-120MB까지 올라간 다음 75-80MB로 줄입니다.

더 많은 링크에서 VM 트래커의 더티 크기 및 상주 크기를 살펴 봅니다. VM Tracker를 체크인하면 Dirty 크기가 30MB부터 시작되어 앱을 사용함에 따라 증가하기 시작합니다. 그것은 400MB를 넘습니다. 저는 약 70-80이 1024x1024 크기 인 약 150 개의 이미지를 사용하고 있습니다. 약 35 개는 110x110이고 나머지는 3000x4000 크기의 이미지입니다. 이 모든 이미지는 원래 png 형식으로되어 있었으며 프로그램 방식으로 JPG + ALPHA로 변환하여 애셋으로 응용 프로그램에 추가했습니다. 해당 이미지를로드해야 할 때마다 JPG + ALPHA 이미지를 16 부분으로 나누고 마지막으로 결합하여 원본 이미지를 얻습니다. 해상도 3000x4000의 이미지를로드하려고 시도 할 때 메모리가 할당에서 40-45MB까지 급상승했기 때문에이 방법을 사용했습니다. 이 방법은 메모리가 10MB를 초과하지 않도록합니다.

이러한 모든 기록 및 통계는 시뮬레이터를 사용하여 측정됩니다.

응용 프로그램은 시뮬레이터에서 충돌하지 않지만 실제 장치에서는 충돌합니다. iPad2를 테스트 용으로 사용하고 있습니다.

이 문제를 해결하는 데 도움을주십시오. 나는 지난 2 일 동안 붙어있어 앱 충돌을보고 완전히 좌절했습니다.

+1

'힙샷'을 검색하면 할당 도구의 기능입니다. 당신은 특정 시간 간격으로 alloc'd 및 dealloc 된 메모리를 추적 할 수 있습니다. 또한, 일부 이미지 처리 메소드는 'imageNamed'와 같은 캐시를 사용합니다. 'NSAutoreleasePool'을 시도해 볼 수도 있습니다. 동시에 많은 양의 이미지가 메모리에 있기 때문입니다. – Templar

+0

크래시 로그의 내용은 무엇입니까? –

+0

@Templar 답장을 보내 주셔서 감사합니다. 나는 어디에서나 NSAutoreleasePool을 사용했고 initWithContentsOfTheFile을 사용하여 이미지의 내용을로드했습니다. 힙샷으로 시도하고 여기에 결과를 게시합니다. – Srikanth

답변

0

이 코드가 맞습니까?

UIImageView* framebadgeOrAccessoryImage = [[UIImageView alloc]initWithFrame:sizeOfFrameOrAccessoriesView]; 
    [framebadgeOrAccessoryImage setCenter:imageArea.center]; 
    [framebadgeOrAccessoryImage setContentMode:UIViewContentModeScaleAspectFit]; 
    [framebadgeOrAccessoryImage setImage:badgeOrAccessoryImage]; 
    [framebadgeOrAccessoryImage setTag:iObjectTag]; 
    [framebadgeOrAccessoryImage setObservationInfo:@"BadgeAccessories"]; 
    [framebadgeOrAccessoryImage setExclusiveTouch:YES]; 

    iObjectTag++; 

    [framebadgeOrAccessoryImage setMultipleTouchEnabled:YES]; 
    [framebadgeOrAccessoryImage setBackgroundColor:[UIColor clearColor]]; 
    [framebadgeOrAccessoryImage setUserInteractionEnabled:YES]; 

    [imageArea addSubview:framebadgeOrAccessoryImage]; 

selectedItem = framebadgeOrAccessoryImage; 

    [framebadgeOrAccessoryImage release]; 

내가 설정 한 태그를 사용하여 내 다른 방법에서 "framebadgeOrAccessoryImage"를 사용하고 있습니다. 코드의 마지막 줄에서했던 것처럼 "framebadgeOrAccessoryImage"를 릴리스해야합니까, 아니면 해제 한 후에 nil에 할당해야합니까?

"framebadgeOrAccessoryImage"는 여기에서 "selectedItem"이라는 이름으로 사용됩니다.

- (void)panRecognized:(UIPanGestureRecognizer *)gestureRecognizer 
{ 
    if(selectedItem.image && [gestureRecognizer isEnabled]) 
    { 
     UIImageView *piece = selectedItem; 

     if ((([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged)) && [((NSString*) [piece observationInfo]) isEqualToString:@"BadgeAccessories"]) 
     { 
      CGPoint translation = [gestureRecognizer translationInView:[piece superview]]; 
      [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y + translation.y)]; 
      [gestureRecognizer setTranslation:CGPointZero inView:[piece superview]]; 

     } 

     if ([gestureRecognizer state] == UIGestureRecognizerStateEnded ||[gestureRecognizer state] == UIGestureRecognizerStateCancelled || [gestureRecognizer state] == UIGestureRecognizerStateFailed) 
     { 
      if(CGRectContainsPoint([[self view]viewWithTag:RECYCLEBIN_TAG].frame, [gestureRecognizer locationInView:imageArea])) 
      { 
       NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init]; 
       [objectsAdded removeObjectForKey:[NSString stringWithFormat:@"%d",selectedItem.tag]]; 
       [pool release]; 
       [UIView beginAnimations:NULL context:nil]; 
       [UIView setAnimationBeginsFromCurrentState:YES]; 
       [UIView setAnimationDuration:0.4]; 
       [UIView setAnimationDidStopSelector:@selector(propDeleted:finished:context:)]; 
       [UIView setAnimationDelegate:self]; 

       [selectedItem setFrame:CGRectMake(selectedItem.frame.origin.x, selectedItem.frame.origin.y, 5, 5)]; 
       selectedItem.center = [[[self view]viewWithTag:RECYCLEBIN_TAG]center]; 
       [UIView commitAnimations]; 
      } 
      else 
      { 
       [self applyEffectOnTouch:0]; 
      } 
     } 
    } 
} 
+1

'framebadgeOrAccessoryImage'를 사용하는 다른 코드를 보여주십시오. 문제의 가능성이있는 것 같습니다. 그러나 제발, 당신의 코드를 여기에 두지 마십시오. 이 영역은 답변입니다. 질문 아래의 ** 수정 ** 링크를 사용하여 코드를 질문에 넣으십시오. 감사. – Nate

0

로드하려는 이미지가 매우 큽니다. 아마도 CATiledLayer를 사용하여 이미지를 표시하는 것을 고려해야합니다. Apple 클래스 정의 here을 찾을 수 있습니다.

또한 이미지를 쉽게 렌더링하는 것보다 사진의 메모리 사용을 줄이는 것의 차이점을 고려하십시오. 이미지를 작은 조각으로 분할하면 개별 그리기로드가 줄어들지 만 각 이미지가 메모리에로드되면 메모리 문제가 발생합니다.

타일링 된 레이어는 매우 큰 이미지를 표시하고 보이는 타일 만로드하여 메모리 사용량을 줄입니다.

또한 시뮬레이터에는 실제 장치의 메모리 제한이 없습니다. 실제 장치에서 모든 스트레스 테스트를 수행해야합니다.

편집 : 또한 UIImage imageNamed를 사용하면 이미지가 캐시되므로 메모리 문제가 더욱 악화 될 수 있습니다. 대신 imageWithContentsOfFile을 사용하십시오.

+0

감사합니다. "imageWithContentsOfFile"메서드를 사용하고 있습니다. 내 번들에서 JPG + ALPHA로 구분 된 이미지가 있기 때문에 화면에 표시하기 전에 이미지를 png 파일로 변환해야합니다. 이전에 JPG + ALPHA를 png로 변환해야하기 때문에 CATiledLayer를 사용할 수 없습니다. 이전 게시물에서 설명한 것처럼 Allocations는 메모리를 최대 7-7.5MB까지 기록하지만 Dirty 크기는 VM Tracker에서 약 400MB에 도달합니다. 더티 사이즈를 줄이거 나 메모리의 일부를 어떻게 청구 할 수 있습니까? – Srikanth

관련 문제