2011-03-28 4 views
3

상당히 적은 메모리 사용 공간을 유지하면서 상당히 큰 CoreData 가져 오기 (약 25,000 행)를 수행하려고합니다. 효율적인 데이터 가져 오기를 다루는 문서를 읽고 거기에 제안 된 모든 것을 구현하기 위해 노력했습니다. (내 MOC의 undoManager와 같은 설정은 무효로합니다.)CoreData 가져 오기 중 메모리 사용량이 많습니다.

아래 코드를 실행하면 내 응용 프로그램의 메모리 사용량이 여전히 약 180MB까지 올라갑니다. 완료되면 응용 프로그램은 최종 NSAutoreleasePool 드레인 호출에 관계없이 180MB 표시 부근에 있습니다.

할당을 통해 응용 프로그램을 실행하면 메모리 사용량의 95 %가 내 [self.moc save:&error] 호출에 기인 한 것으로 나타납니다. 여기서 내가 뭘 잘못하고 있니?

- (void)generateCache 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSUInteger count = 0, batchSize = 1000; 

    // SNIP SNIP 

    // Iterate over our directory structure 
    for(NSString *item in directoryStructure) 
    { 
     NSDictionary *info = [fm attributesOfItemAtPath:item error:nil]; 

     FileRecord *record = (FileRecord *)[NSEntityDescription insertNewObjectForEntityForName:@"FileRecord" inManagedObjectContext:self.moc]; 
     record.size = [NSNumber numberWithUnsignedLongLong:[info fileSize]]; 
     record.path = item; 

     count ++; 
     if(count == batchSize) 
     { 
      NSError *error = nil; 

      if([self.moc save:&error]) 
      { 
       NSLog(@"MOC saved down and reset"); 
       [self.moc reset]; 
       [pool drain]; 

       pool = [[NSAutoreleasePool alloc] init]; 
       count = 0; 
      } 
     } 
    } 

    // Perform any necessary last minute MOC saves 
    if (count != 0) { 
     [self.moc save:nil]; 
     [self.moc reset]; 
    } 

    // Drain our NSAutoreleasePool 
    [pool drain]; 

    // Tell our main thread that we're done 
    if ([self respondsToSelector:@selector(completedCache)]) 
    { 
     [self performSelectorOnMainThread:@selector(completedCache) withObject:nil waitUntilDone:NO]; 
    } 
} 
+0

저장으로 인해 생성 된 오류는 로깅하지 않습니까? 또한, 수입에 의해서만 사용되는 MOC입니까? –

답변

1

대신 자동 해제 풀을 다루는, 왜 안 명시 적으로 NSManagedObjectinitWithEntity:insertIntoManagedObjectContext:로를 작성하여 관리 객체의 생명주기를 관리? 관리 대상 객체 컨텍스트는 지속적으로 영구 저장소에 저장 될 때까지 새로 삽입 된 객체를 유지하므로 객체의 속성을 수정 한 후에 안전하게 해제 할 수 있습니다. save: 작업에서

사람이 위에서 언급 한 바와 같이
  1. , 당신은 로그인되지 않은 오류 :

    또한, 나는 내가 당신의 코드를 참조 몇 가지 문제를 언급해야한다. 당신은 정말로해야합니다 - 그것은 아마도 (관련이없는) 일부 문제를 강조 할 수 있습니다.

  2. 저장 : 성공한 경우 실제로 reset으로 전화하지 않아도됩니다. 핵심 데이터 가이드의 this section을 참조하십시오.

+0

그는 그 방법으로 풀을 가지고 있습니다. autorelease를 위해 설정된 객체를 릴리즈하지 않았습니까? –

+0

예, 모든 'batchSize' 객체가 반복 된 후에 만 ​​가능합니다. 내 요점은 실제로 autorelease'd 개체의 (약간의) 추가 복잡성을 제거하는 것이 었습니다. 문제가 해결되지 않더라도 최소한 간단한 코드로 끝나고 디버그하기 쉽습니다. –

+0

+1 답변을 설명합니다. –

관련 문제