ARC란? ARC이해하기 [Part-1]

ARC란? Automatic Reference Counting의 약어로서
완전한 ARC는 XCODE 4.2, iOS 5 부터 지원했습니다.

애플 공식 문서에 따르면 ARC는 iOS 4부터 ARCLite 라는 이름으로 추가 되었습니다.
Automatic Reference Counting without zeroing weak reference (“ARCLite)
즉 weak 키워드를 지원하지 않는 ARC 입니다
*약한 참조 제로화 : 객체가 할당 해제를 시작하기 직전에 약한(weak) 참조를한 지역 변수, 인스턴스 변수 및 선언 된 속성을 자동으로 지우는 것(nil로 만듬)

ARC는 LLVM 3.0 컴파일러부터 추가된 기능이며 컴파일 타임(compile time) 에 컴파일러가 자동으로 프로그램의 올바른 위치에 retain, release , autorelease를 자동으로 삽입합니다. 런타임 중에는 별도의 메모리 관리가 이루어 지지 않습니다.

func someFunction() {
    var property = SomeClass()
    doWork(property)
}

// 위 코드는 ARC에 의해 아래와 같은 코드로 변경되어 컴파일된다.
func someFunction() {
    var obj = SomeClass()
    obj.retain()       // ARC가 추가한 코드

    doWork(obj)

    obj.release()      // ARC가 추가한 코드
}

*컴파일러란? Swift 와 같은 고수준 언어로 쓰여진 소스 코드를 저수준언어(어셀블리어, 기계어 등)으로 번역하는 프로그램을 의미

ARC가 나오기 전에는 MRC (Manual Reference Counting) 로 개발자가 수동으로 메모리 관리를 했습니다. 인스턴스(object)를 생성(retain, alloc등)하고 생성한 객체가 더이상 사용 되지 않는 부분에서 [object release]; 와 같은 해제 명령어를 삽입했습니다. .

*JAVA,ANDROID 가비지 컬렉션( GC or Garbage Collection)은 프로그램 실행 중(Runtime) 동적으로 감시하고 있다가, 더 이상 사용할 필요가 없다고 여겨지는 것을 소멸(해제) 시킵니다.

Swift는 ARC를 사용하여 앱의 메모리 사용량을 추적하고 관리합니다. 대부분의 경우 이는 메모리 관리를 Swift에서 알아서 한다는 것을 의미하며 메모리 관리에 대해 개발자가 생각할 필요가 없습니다. ARC는 해당 인스턴스가 더 이상 필요하지 않을 때 클래스 인스턴스에서 사용하는 메모리를 자동으로 해제합니다.
즉 , 클래스 인스턴스가 속성(properties), 상수(constants) 및 변수(variables) 등으로 부터 참조 되면 레퍼런스 카운트 1이 증가하며 여러개의 변수에서 참조되면 레퍼런스 카운트는 n 개가 됩니다. ARC 는 참조되는 레퍼런스 카운트가 0 이되면 자동으로 메모리에서 해제하는 것입니다.

레퍼런스카운팅(Reference Counting)*참조횟수클래스 인스턴스에만 적용됩니다. 구조체(Structures)와 열거형(enumerations)은 레퍼런스 타입(Reference type)이 아니라 값 타입(Value types) 이며 참조(Reference)로 저장 및 전달되지 않습니다.
[참조 타입과 값 타임 알아보기]

ARC의 작동 원리

특정 클래스의 새로운 인스턴스를 만들 때마다 ARC는 해당 인스턴스에 대한 정보를 저장하기 위해 적당한 크기의 메모리를 할당합니다. 이 메모리는 해당 인스턴스와 관련된 프로퍼티 값과 함께 인스턴스 유형에 대한 정보를 보유합니다.

또한 인스턴스가 더 이상 필요하지 않은 경우 ARC는 해당 인스턴스에서 사용하는 메모리를 해제하여 메모리를 다른용도로 사용할 수 있도록합니다. 이렇게 하면 클래스 인스턴스가 더 이상 필요하지 않을 때는 메모리 공간을 차지하지 않게 됩니다.

만약 ARC가 아직 사용중인 인스턴스의 메모리를 해제한다면 더 이상 해당 인스턴스의 프로퍼티에 접근 하거나 해당 인스턴스의 메서드를 호출 할 수 없게 될것입니다. 실제로 인스턴스에 액세스 하려고하면 런타임 에러가 발생될것입니다.

ARC는 인스턴스가 여전히 필요한 동안 메모리에서 사라지지 않도록 현재 각 클래스 인스턴스를 참조하는 속성(properties), 상수(constants) 및 변수(variables)를 추적합니다. ARC는 해당 인스턴스에 대한 참조(Reference)가 하나 이상 존재하는 한 인스턴스를 메모리에서 해제하지 않습니다.

이를 가능하게 하기 위해 속성(property),상수(constant) 또는 변수(variable)에 클래스 인스턴스를 참조 할 때마다 해당 속성,상수 또는 변수는 인스턴스에 대한 강력한참조를 만듭니다. 해당 인스턴스를 확고하게 유지하고 강력한 참조가 유지되는 한, 메모리에서 제거 되지 않기 때문에 “강한참조(strong reference)” 라고 표현합니다.

ARC 의 동작

다음은 ARC의 작동 방식에 대한 예입니다. 이 예제는 name이라는 상수 프로퍼티를 정의하는 Person이라는 간단한 클래스로 시작합니다.

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}

Person 클래스에는 인스턴스의 name 프로퍼티를 설정하고 초기화가 진행 중임을 나타내는 메시지를 프린트하는 이니셜 라이저가 있습니다. Person 클래스에는 클래스의 인스턴스가 메모리 해제 될 때 메시지를 프린트하는 deinitializer도 있습니다.

다음 코드는 Person 인스턴스에 대한 여러 참조를 설정하는 데 사용되는 Person? 옵셔널타입의 세 가지 변수를 정의합니다. 이러한 변수는 옵셔널타입*선택적 유형(optional type) 이기 때문에 자동으로 nil 값으로 초기화되며 현재 Person 인스턴스를 참조하지 않습니다. [옵셔널 알아보기]

var reference1: Person?
var reference2: Person?
var reference3: Person?

Person 클래스 타입을 갖는 3개의 참조타입의 변수를 3개 만들었습니다.

reference1 = Person(name: "John Appleseed")
// Prints "John Appleseed is being initialized"

reference1 에 Person 인스턴스를 생성해 참조하게 했습니다.

reference2 = reference1
reference3 = reference1

reference2, reference3 에는 reference1를 참조하게해서 결론적으로
단일 인스턴스(Person)에 대해 3개의 강한참조가 생성되었습니다. (Reference count 3)

reference1 = nil
reference2 = nil

두개의 변수에 nil을 할당하여도 reference3에서 참조하고 있기 때문에
ARC는 세 번째이자 마지막 강한참조가 끊어 질 때까지 Person 인스턴스를 메모리에서 해제하지 않습니다
(Reference count 1)

reference3 = nil
// Prints "John Appleseed is being deinitialized"

위의 시점에서 더 이상 Person 인스턴스가 참조되지 않아 메모리 해제되는 것이 분명합니다.(Reference count 0)

ARC 가 메모리관리에 대한 모든것(100%)을 해주는것은 아닙니다.
경우에 따라 ARC는 메모리 관리를 위해 특정 코드간 관계에 대한 추가 정보를 요구합니다.


다음 글에서 이에관련한 클래스 인스턴스간의 강한참조로 인한 문제에대해 다뤄보기로 하겠습니다.

스위프트 공식 사이트인 https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html 의 문서를 번역하고 내용을 첨가했습니다.

에 발행했습니다
SWIFT(으)로 분류되었습니다

aaron님이 작성

아무것도 안해도 시간은 흐른다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다