Auto Reference Counting의 줄임말로, Swift에서 앱의 메모리 사용을 관리하기 위해 사용한다. ARC가 참조 횟수를 관리하기 때문에 더 이상 사용하지 않는 인스턴스를 메모리에서 해제한다. 따라서 ARC는 개발자가 메모리를 관리해야 하는 짐을 덜어주지만 완전히 책임을 지는 게 아니다. 우선 ARC가 어떻게 동작하는지 알아보자.
클래스의 새 인스턴스를 만들 때마다 인스턴스의 정보를 담는데 필요한 메모리를 할당한다. 그리고 인스턴스가 더 이상 사용되지 않을 때, ARC는 인스턴스가 차지하고 있는 메로리를 해제해서 공간을 확보한다. 중요한 점은, ARC는 컴파일 타임에 컴파일러가 개발자를 대신하여, 메모리를 관리하는 코드를 적절한 위치에 삽입한다.
이러한 ARC의 동작 방식은 Garbage Collection과 차이가 있다. Garbage Collection은 런타임에 메모리 관리를 수행한다. 프로그램이 실행되는 동안 동적으로 감시를 하므로, Garbage Collection을 위한 메모리가 필요하다. 또한 지속적인 감시를 위해 CPU를 일부 사용해야한다. 하지만 ARC에 비하여 인스턴스가 해제될 확률이 높다.
ARC에서는 아직 사용 중인 인스턴스의 메모리를 해제하지 않기 위해 인스턴스를 참조하는 프로퍼티, 상수 및 변수의 수를 추적한다. 해당 인스턴스에 대한 참조가 하나 이상 존재하는 한 인스턴스의 메모리를 해제하지 않는다. 이를 위해 프로퍼티, 상수 또는 변수에 클래스 인스턴스를 할당할 때마다 해당 프로퍼티, 상수 또는 변수는 인스턴스에 대한 강한 참조를 만든다. 인스턴스에 대한 강한 참조가 남아 있는 한 메모리의 해제를 허용하지 않기 때문에 '강한' 참조라고 한다.
class Person {
let name: String
init(name: String) {
self.name = name
}
}
실제로 ARC가 어떻게 동작하는지 살펴보기 위한 Person
클래스가 있다. 그리고 ARC가 클래스 인스턴스의 참조 횟수에 따라 어떻게 동작을 하는지 알아보기 위해 Person 타입을 갖는 세 개의 변수를 선언한다. 이 변수는 Optional 변수로 초기값으로 nil
을 가지고 있다.
var reference1: Person?var reference2: Person?var reference3: Person?
새로운 Person
클래스의 인스턴스를 생성하고 refercen1
에 할당한다. 이때 Person
인스턴스에 대한 강한 참조가 생겨서, ARC는 인스턴스가 메모리에서 유지되도록 한다.
reference1 = Person(name: "John")
reference1
에 할당한 Person
인스턴스를 reference2
와 reference3
변수에 할당하면, Person
인스턴스는 3개의 강한 참조가 존재한다.
reference2 = reference1
reference3 = reference1
이제 reference1
과 reference2
에 nil
값을 설정해서 메모리에서 해제한다. 그러면 Person
인스턴스에 대한 2개의 강한 참조가 사라진다. 하지만 reference3
에 대한 강한 참조가 남아있어 ARC는 Person
인스턴스를 메모리에서 해제하지 않는다.
reference1 = nil
reference2 = nil
마지막으로 reference3
에 대한 강한 참조를 해제하면, ARC는 더 이상 Person
인스턴스를 사용하지 않는다고 판단하여 메모리에서 해제한다.
reference3 = nil