2013-05-28 3 views
1

ARC을 사용하는 경우 @autoreleasepool{}의 객체는 더 이상 사용하지 않을 때 해제해야합니다. 그러나목표 C - autoreleasepool 및 ARC 누출 메모리

코드

#import <Foundation/Foundation.h> 

int main(int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     for (int i = 0; i < 1000000000; i++) { 
      NSString *string = @"ab c"; 
      NSArray *array = [string componentsSeparatedByString:string]; 
     } 
    } 
    return 0; 
} 

누출 메모리. 객체를 유출

악기 쇼에서 __NSArrayM 생성 - [있는 NSString componentsSeparatedByString :]

그래서, 질문은 왜 __NSArrayM 오브젝트는 작성 동일한 루프 반복에서 파괴되지 않습니다?

사람이 문제를

업데이트 해결을 도와 수 : 감사는 답을, 내가 잘못 용어 "메모리 누수"를 사용하고, 오해 방법 @autoreleasepool{} 작품 보인다. 이 문제를 해결하려면 for 루프 안에 @autoreleasepool{}을 배치해야합니다.

+2

이 코드는 많은 메모리를 할당하지만 유출되지 않습니다. – stosha

+0

누수가 발생했다는 것을 알고 있다면 왜 그렇게 큰 루프를 반복하여 한 번의 반복 작업만으로 증명할 수 있습니까? :) –

+1

사실이 질문에 대한 좋은 예라고 생각합니다. 나는 왜 그것이 많은 downvotes를 얻었는지 모르겠다. –

답변

3

enter image description here는 오토 릴리즈 작품, 원본을 아래에이 코드를 비교하는 방법을 이해하려면 :

for (int i = 0; i < 1000000000; i++) 
{ 
    @autoreleasepool 
    { 
     NSString* string = @"ab c"; 
     NSArray* array = [string componentsSeparatedByString:string]; 
    } 
} 

가 범위 밖으로 갈 때 객체가 출시 표시됩니다 자동 발표, 실제로 해제되지 않은 autorelease 섹션의 끝까지 (autorelease 풀이 비게되는 곳).위의 코드는 매번 루프 주위에서 표시된 객체를 해제하지만 원래 코드는 루프의 끝 부분에서만 모두 해제합니다.

자동 릴리스 풀은 중첩 될 수 있으며 객체가 자동으로 릴리즈 될 때 가장 가까운 풀이 사용됩니다. 이것은 [NSString stringWithFormat:@"%d", i];과 같은 함수에서 객체를 반환 할 수 있습니다. 반환 된 문자열의 보유 수는 1이지만 자동 릴리스로 표시됩니다. 일시적으로 사용할 수 있지만 나중에 사용하기 위해 유지해야하는 경우 (예 : 그것을 강력한 참조에 지정하면 발생합니다). 따라서 보유 수를 유지하면 보유 수는 2로, 자동 해제되면 보유 수는 1로 모두 모두 양호합니다. 유지하지 않으면 자동으로 해제 될 때 보유 개수가 0이되고 객체가 할당 해제됩니다.

3

이해 이것은 그들이

  • 오토 릴리즈 풀 버전 객체를 사용 중지 할 때 그것은 개체가 해제되지 않은하지 가비지 컬렉션, 그래서 ARC
  • 함께 할 아무것도하지 않는

    1. 잘못 물기가 빠졌거나 ([NSAutoreleasePool drain]) 파괴되었습니다. 수영장을 명시 적으로 배수하지 않으므로 return 직전에 한 번만 배수됩니다. ARC가 활성화 된 경우 그들은 더 이상 사용하지 않을 때 나의 이해에서
  • +0

    GC가 심지어 1 억 개의 객체를 할당하려고 시도했을 경우에도 마찬가지입니다. – CodaFi

    +0

    @CodaFi 글쎄, GC는 매 반복마다 객체를 쉽게 해제 할 수 있습니다. 그러나 더 큰 문제는 다른 스레드가 제대로 작동하지 못하게하는 "거의 무한한"루프 일 것입니다. GC 구현에 따라 달라집니다. – Sulthan

    +0

    OS X 가비지 컬렉터가 낮은 우선 순위의 백그라운드 스레드 IIRC에서 실행되었으므로 이러한 상황에서 "멈추는 세상"이 될 수 있습니다. (단지 루프로 충만해질 수도 있습니다) – CodaFi

    3

    는, @autoreleasepool 내부 객체는 {} 발표한다.

    OK, 한발 물러서서 실제로 잠시 생각해보십시오. ARC는 모든 메모리 누출에있어 마술 같은 것이 아닙니다. 여전히 수동으로 릴리즈됩니다. 컴파일러는 수동으로 릴리즈 할 수 있습니다. @autoreleasepool {}은 "메모리 누수"의 예제를 제공 할 때 신중함을 피할 수 없으며 10 억 개의 개체를 할당 할 수있는 권한을 부여하지 않으며 프레임 워크 버그라고도합니다. 그것으로 밝혀 졌을 때, 당신이 한 일은 아마 autorelease pool에 과부하가 걸려 있고 루프가 제대로 끝나기를 기다리지 못하거나 OS에 의해 죽을 것입니다. 후자에 더 많은 것). 이 프로그램을 실행하면 주어진 자동 릴리스 풀이 할당 된 RAM의 메모리를 소모한다는 것을 확인할 수 있습니다.

    당신은 루프를 제거하거나 단축의 기간 (100, 또는 1000 충분합니다), 당신은 절대적으로 객체의 누설이 없다는 것을 확인하실 수 있으며, 모든 것이 올바르게 공룡의 길을가는 경우 :

    +0

    매우 멋진 대답 . – Mike