참조 타입은 하나의 인스턴스가 참조를 통해 여러 곳에서 접근하기 때문에 언제 메모리에서 해제되는지가 중요한 문제다. 적절한 시점에 인스턴스가 해제되지 않으면 한정적인 메모리 자원을 낭비하게 되고, 이는 성능 저하로 이어진다.
Swift는 프로그램의 메모리 사용을 관리하기 위해 메모리 관리 기법인 ARC (Automatic Reference Counting) 를 사용한다.
ARC가 관리해주는 Reference Counting (참조 횟수 계산) 은 참조 타입인 클래스의 인스턴스에만 적용된다.
구조체나 열거형은 값 타입으로 다른 곳에서 참조하지 않기 때문에 ARC로 관리할 필요가 없다.
ARC는 자동으로 메모리를 관리해주는 방식이다. 대부분의 경우 메모리 관리는 Swift에서 "그냥 작동"하기 때문에, 개발자는 메모리 관리에 대해 신경을 덜 쓸 수 있다.
클래스의 인스턴스가 생성되면 해당 인스턴스의 정보는 HeapObject라는 struct로 관리된다.
ARC의 메커니즘은 Swift Runtime이라는 라이브러리에 구성되어 있는데, Swift Runtime은 동적 할당 되는 모든 모든 object를 HeapObject라는 struct로 표현한다. 또한 HeapObject에서는 Swift에서 객체를 구성하는 모든 데이터, 즉 reference count와 type meta data를 포함하고 있다.
ARC는 인스턴스가 더 이상 필요하지 않다면 해당 인스턴스를 메모리에서 해제시킨다.
그런데 알고보니 인스턴스가 다른데에서 또 사용되어야 한다면?
따라서 ARC는 해당 인스턴스를 참조하는 다른 인스턴스의 프로퍼티나 변수, 상수 등의 개수를 세고, 해당 인스턴스에 대한 활성 참조가 1개 이상 존재하는 한 인스턴스를 메모리에서 없애지 않는다. 위에서 설명한 heapObject의 referenceCount가 활성 참조라고 보면 된다.
가비지 컬렉션(GC)은 자바, C# 등에서 사용되는 메모리 관리 기법이다.
ARC와 GC의 가장 큰 차이는 참조를 카운팅 (Reference Counting) 하는 시점이다.
GC와 다르게 ARC는 컴파일과 동시에 인스턴스를 메모리에서 해제하는 시점을 결정하기 때문에 ARC를 이용해 우리가 원하는 방향으로 메모리 관리가 이루어지려면 ARC에 명확한 힌트를 줘야 한다.
그렇다면 어떻게 힌트를 줄 수 있을까?
다음 편에 계속 ..
https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
https://sujinnaljin.medium.com/ios-arc-%EB%BF%8C%EC%8B%9C%EA%B8%B0-9b3e5dc23814
스위프트프로그래밍 3판 - 야곰
ARC도 런타임에 레퍼런스 카운팅을 합니다. 스위프트에서 말하는 "컴파일타임 ARC" 는 release 코드의 삽입에 대해서 말하는것 아닌가요