19·iOS 면접문제·ARC란 무엇인가?(ARC는 어떤 문제를 해결하기 위해 탄생했습니까?)

4340 단어

전언


iOS 메모리 파티션에는 스택, 스택, 정적 파티션, 전역 파티션, 상수 파티션, 코드 파티션이 있습니다.정적 구역, 전역 구역, 상수 구역, 코드 구역에 대해 대상의 생명 주기는 응용의 생명 주기와 함께 상주 메모리이기 때문에 우리가 대상 메모리를 관리할 필요가 없다.창고 구역의 대상에 대해 창고가 선진적인 후출의 원칙에 따라 시스템이 자동으로 우리를 도와 관리하고 우리가 대상의 메모리를 관리할 필요가 없다.퇴적 구역의 대상에 대해 우리는 스스로 메모리를 개척하고 방출해야 한다. 프로그램 개발에서 메모리 관리의 가장 중요한 것은 퇴적 구역의 메모리 관리이다.
iOS에서 인용 계수 메커니즘을 사용하여 메모리 관리를 한다. 처음에는 MRC(수동 인용 계수)를 사용한 다음에 점차적으로 ARC(자동 인용 계수)로 바뀐다. 여기서 인용 계수 메커니즘의 원리, MRC와 ARC의 일부 특성을 소개하고 마지막으로 자바가 대상 메모리를 어떻게 관리하는지 살펴본다.

참조 계수 메커니즘


Objective-C에서 인용 계수를 이용하여 메모리 관리를 한다. 모든 대상은 대응하는 인용 계수를 가지고 있다. 이 대상이 보유되었을 때 인용 계수는 증가하고 이 대상의 어떤 보유자가 방출되었을 때 대상의 인용 계수는 감소하며 이 대상의 인용 계수가 0일 때 이 대상은 방출된다.
모든 대상은 인용 계수에 대응하고 메모리에는SideTable RefcountMap을 통해 이 대응 관계를 저장합니다. 대상의 주소는 Key이고 인용 계수의 값은Value입니다.
객체의 참조 개수 증가 및 감소 핵심 코드는 다음과 같습니다.
//          
id objc_object::sidetable_retain()
{
    //  table
    SideTable& table = SideTables()[this];
    //  
    table.lock();
    //      
    size_t& refcntStorage = table.refcnts[this];
    if (! (refcntStorage & SIDE_TABLE_RC_PINNED)) {
         //      
        refcntStorage += SIDE_TABLE_RC_ONE;
    }
    //  
    table.unlock();
    return (id)this;
}

//         
    SideTable& table = SideTables()[this];
    bool do_dealloc = false;
    table.lock();
    //       
    RefcountMap::iterator it = table.refcnts.find(this);
    if (it == table.refcnts.end()) { //     ,  dellloc
        do_dealloc = true;
        table.refcnts[this] = SIDE_TABLE_DEALLOCATING;
    } else if (it->second < SIDE_TABLE_DEALLOCATING) {//        ,dealloc
        do_dealloc = true;
        it->second |= SIDE_TABLE_DEALLOCATING;
    } else if (! (it->second & SIDE_TABLE_RC_PINNED)) {
    //      1
        it->second -= SIDE_TABLE_RC_ONE;
    }
    table.unlock();
    if (do_dealloc  &&  performDealloc) {
        //  dealloc
        ((void(*)(objc_object *, SEL))objc_msgSend)(this, SEL_dealloc);
    }
    return do_dealloc;

MRC 수동 참조 개수


MRC 수동 인용 계수에 대해 프로그래머가 수동으로 호출retain,release,autorelease 이런 방법으로 대상의 인용 계수를 제어해야 한다. 이런 상황에서 개발자는 많은 정력을 들여 메모리 관리를 해야 하고 방출된 대상release이 쉽게 나타나 프로그램이 붕괴된다.
위의 세 가지 방법의 각각의 역할에 대해 다음과 같이 소개한다.
  • retain 증가 대상의 인용 계수.
  • release는 대상 인용 계수를 낮추고 인용 계수가 0일 때 대상을 방출한다.
  • autorelease는 현재 autorelease pool이 끝난 후 대상 인용 계수를 낮춥니다.

  • ARC 자동 참조 개수


    MRC 환경에 나타난 문제에 대해 ARC 자동 인용 계수는 컴파일러가 지능적으로 우리를 도와 합리적인 곳에 은밀하게 추가retain,release,autorelease방법(PS: 이 몇 가지 방법을 간단하게 삽입하는 것이 아니라 이에 대응하는 밑바닥 방법을 삽입하여 어느 정도 최적화 집행 효율을 높이는 것이다).ARC는 메모리 관리를 용이하게 하지만 ARC에는 다음과 같은 단점이 있습니다.
  • CoreFoundation의 대상을 관리할 수 없기 때문에CoreFoundation 대상에 대해 수동으로 메모리를 관리해야 한다
  • 순환 인용 대상을 방출할 수 없다(여기도 ARC 부족은 아니지만 이것은 인용 계수 메커니즘 자체의 단점이다)
  • Java는 GC를 사용하여 메모리 관리


    우리는 Objective-C에서 인용 계수 메커니즘을 이용하여 메모리를 관리하는 것을 이미 알고 있다.그러나 자바 개발에서는 Garbage Collection 스팸 회수 메커니즘을 사용하여 메모리 관리를 한다(사실 Objective-C는 초기에도 이 모델을 사용했지만 뒤에 인용 계수 메커니즘으로 전환되었다).
    스팸 수거(Garbage Collection)는 JVM(Java Virtual Machine) 스팸 수거기가 빈 시간에 대상이 인용하지 않은 대상이 차지하는 메모리 공간을 부정기적으로 회수하는 메커니즘이다.
    쓰레기 수거 메커니즘의 경우 두 가지 논리를 처리해야 한다.
  • 살아있는 모든 대상을 찾습니다.
  • 쓸모없는 대상이 차지하는 메모리 공간을 회수하여 프로그램이 다시 사용할 수 있도록 한다.

  • 생존 대상을 찾다


    루트 검색 알고리즘을 이용하여 살아있는 대상을 찾고 살아있는 대상을 표시하면 표시되지 않은 대상은 다음 단계에서 삭제됩니다.(PS: 태그를 지정하기 전에 프로그램이 일시 중지되어 버퍼링이 발생)

    쓰레기 수거 대상 메모리


    쓰레기 회수 대상의 메모리에 대해 서로 다른 상황에 따라 서로 다른 알고리즘으로 회수할 수 있다. 어떻게 선택하는지 참고할 수 있다. JAVA의 쓰레기 회수 메커니즘(GC)
  • 태그 - 지우기 알고리즘
  • 태그 - 정리 알고리즘
  • Copying 알고리즘
  • Adaptive 알고리즘
  • 참조 계수 메커니즘과 GC의 차이점:
  • 인용계수는 컴파일 시기에 코드를 삽입하고 대상이 사용되지 않으면 즉시 회수한다.GC는 일정 시간 동안 여러 번 회수 대상을 진행하면 렉이 걸릴 수 있다.
  • 인용 계수가 순환 인용 문제를 잘 처리하지 못하면 GC가 처리할 수 있다.
  • 인용계수는 프로그램이 실행하는 비용을 증가시키는데 GC는 상대적으로 간단하다.

  • 총결산


    이 글을 통해 Objective-C는 인용 기술을 사용하여 메모리를 관리하고, MRC를 ARC로 전환하는 것이 어떤 장점이 있는지 알 수 있으며, 자바가 GC를 이용하여 메모리 관리를 하는 것도 간단하게 알 수 있다(더욱 상세한 GC 조작은 참고 링크를 볼 수 있다).
    뒤에 유사한 면접문제가 있기 때문에 우리는 자동 방출지의 밑바닥 실현, weak 수식 대상의 메모리 방출을 잠시 소홀히 했다. 이런 것들은 후속 면접문제에서 하나하나 이야기할 것이다.

    참고 문헌


    ARC-iOS/Mac 개발 ARC 입문 및 사용
    iOS의 MRC에서 ARC까지의 메모리 관리 상세 정보
    JAVA의 쓰레기 회수 메커니즘(GC) 분석

    좋은 웹페이지 즐겨찾기