적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

Swift iOS 앱 개발/Swift

[Swift ARC] Automatic Reference Counting

hongssup_ 2023. 1. 31. 01:26
반응형
Swift에서는 Automatic Reference Counting 방식을 이용하여 메모리 관리를 자동으로 해주고 있다.
참조 타입인 클래스의 인스턴스를 관리할 때 사용되는 방식으로,
클래스의 새 인스턴스를 만들 때마다 ARC는 해당 인스턴스의 정보를 저장하기 위해 메모리에 할당하고,
해당 인스턴스를 참조하는 횟수(reference counting)를 추적하여 더 이상 사용되지 않을 경우 자동으로 메모리를 해제해준다. 

 

Reference Counting이란? 

메모리를 제어하는 방법 중 하나로, garbage collection의 한 방식이다. 

어떤 한 동적 단위(객체, Object)가 참조값을 가지고 이 단위 객체가 참조(참조 복사)되면 참조값을 늘리고 참조한 다음 더이상 사용하지 않게 되면 참조값을 줄이면 된다. 보통 참조값이 0이 되면 더이상 유효한 단위 객체로 보지 않아 메모리에서 제거한다.

이 방식은 단위 객체에 대한 유/무효 처리가 사용하는 자리에서 확실하게 정해지며 참조값을 늘리고 줄이는 방법을 사용하기 때문에 빠르다. 또한 동적 가비지 컬렉션을 하지 않는 프로그래밍 언어에서도 간단하게 구현할 수 있다.

 

장점

- 메모리를 직접 해제하는 번거로움이 사라진다

- 빠르다

단점

- 순환 참조 문제

: 매번 참조할 때마다 참조값을 검사해야 하므로 많은 수의 단위 객체를 사용하게 되면 그 검사에 대한 부하가 커진다. 또한 참조하는 단위 객체 사이에 서로 참조하게 되면 순환 참조 오류로 인해 잘못된 참조 파괴가 생기거나 또는 단위 객체가 고아(orphaned)가 될 수 있다.

 

방식에는 강한 참조(strong reference)와 약한 참조(weak reference)가 있는데, 보통 reference counting 방식을 이야기할 때는 강한 참조를 말하며, 약점으로 지적된 순환 참조 오류를 해소하기 위해 약한 참조를 사용하기도 한다. 

 

* garbage collection : 메모리 관리 기법 중 하나로, 동적으로 할당된 메모리 영역 중에서 필요없게 된 영역을 탐지하여 자동으로 해제하는 기능

 

참고 : https://ko.wikipedia.org/wiki/%EC%B0%B8%EC%A1%B0_%ED%9A%9F%EC%88%98_%EA%B3%84%EC%82%B0_%EB%B0%A9%EC%8B%9D

 

Automatic Reference Counting

Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage.  In most cases, this means that memory management “just works” in Swift, and you don’t need to think about memory management yourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.
However, in a few cases ARC requires more information about the relationships between parts of your code in order to manage memory for you. 
Reference counting applies only to instances of classes. Structures and enumerations are value types, not reference types, and aren’t stored and passed by reference.

Swift 에서는 ARC 를 사용하여 앱의 메모리 사용량을 추적하고 관리한다. 

이는 대부분의 경우 Swift에서 메모리 관리가 자동으로 이루어지기 때문에 메모리 관리에 대해 직접 생각할 필요가 없음을 의미한다.

ARC는 해당 인스턴스가 더이상 필요하지 않을 때 클래스 인스턴스에 사용된 메모리를 자동으로 해제한다. 

reference counting 은 값 타입과는 상관이 없고, 참조 타입인 클래스의 인스턴스 메모리를 관리하는 방식이다.

(value 타입인 struct나 enum은 값이 참조가 되는 것이 아니라 복사되기 때문에 따로 ARC로 관리할 필요가 없음)

 

ARC 의 작동 방식

- 클래스의 새 인스턴스를 만들 때마다 ARC는 해당 인스턴스의 정보를 저장하기 위해 메모리를 할당 (해당 인스턴스의 자료형과 프로퍼티 저장)

- 인스턴스가 더 이상 필요하지 않은 경우 ARC는 해당 인스턴스가 사용하는 메모리를 해제

- ARC가 아직 사용중인 인스턴스를 해제하면 해당 인스턴스의 프로퍼티나 메서드에 접근할 수 없고 앱이 crash날 수 있다.

- 인스턴스가 필요한 동안은 사라지지 않도록, ARC는 현재 각 클래스 인스턴스를 참조하는 properties / constants / variables의 참조 횟수(RC: reference count)를 추적함. 적어도 하나의 참조라도 존재하는 한, ARC는 인스턴스 할당을 해제하지 않는다. 

- 인스턴스는 강한 참조가 유지되는 한 해제할 수 없기 때문에 reference는 "strong" reference라고 함.

보통은 strong reference를 사용하지만, 강한 순환 참조의 문제를 해결하기 위해 weak reference 혹은 unowned reference를 사용하기도.

 

 

Strong Reference Cycle 

ARC가 참조 횟수를 세며 자동으로 메모리 해제를 해주긴 하지만, 강한 참조 횟수가 절대 0이 되지 않는 경우가 발생할 수도 있다. 

두 클래스 인스턴스가 서로 강한 참조를 하고 있을 때 이런 일이 발생할 수 있으며, 이를 강한 순환 참조라고 한다. 

강한 순환 참조 문제를 해결하기 위해 Swift 에서는 weak references 와 unowned references 를 사용할 수 있다. 

 

 


참고 :

https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html

 

 

 

728x90
반응형