티스토리 뷰

728x90

오늘은 ARC에 대해 공부해보려고 합니다!

 

Swift 에서 메모리가 어떻게 관리 되는지,

그동안 참조, Heap은 뭔지 대충만 알고 넘어갔는데 

좀더 깊이 파보려고 해요! 

 

 


ARC란?

 

  • Automatic Reference Counting 의 약자로, 자동으로 메모리를 관리 해줍니다.
  • 객체에 대한 참조 하게 되면 카운트가 +1 되게 하고 0이되면 자동으로 메모리 해제를 시켜줍니다. 
  • Compile time에 실행 됩니다.
  • Objective-C (라떼는...) MRC (Manual Reference Counting)를 사용하여 수동으로 메모리를 해제 시켜줬다고 해요.

아래 사진은 MRC와 ARC의 차이점을 나타내요.

(좌) MRC, (우) ARC

 

MRC의 경우 retain / release를 사용하면서 일일히 참조 카운트를 조정해주는게 보이네요. 

 

ARC의  필요성

 

'그래서 메모리 관리를 왜 해야하는데 ?'

라는 생각이 들었습니다.

 

ARC는 4가지 메모리영역 (Data, Code, Stack, Heap) 중 Heap 영역과 관련이 있습니다. (메모리 구조 내용은 여기)

class, closure 등 참조타입들은 자동으로 Heap에 할당 됩니다. 

또한, 개발자가 동적으로 할당하는 메모리 공간이기 때문에 관리가 필요합니다. 

계속 할당만 되고 해제가 되지않으면 메모리 누수(leak) 현상이 일어나기 때문에 프로그램이 꺼지게 됩니다.

 

근데 알아서 해제해주는 일을 ARC가 담당해주고 있는거죠 !

 

 

ARC의  메모리 관리방법

 

ARC에서 메모리의 참조 카운트 (Reference Count)를 계산하여 

참조 카운트가 0이되면 자동으로 더이상 사용되지 않는다 파악하고 해제 합니다.

 

  • Compile time에 코드 분석을 하며 적절한 위치에 retain, release 의 코드를 삽입해 줍니다.
  • 삽입된 코드는 Run time에 실행됩니다.
  • retain, release를 통해서 reference Count를 증감 시키다 count가 0이 될때 deinit을 통해 메모리에서 해제 시킵니다.

 

ARC의 단점 및 weak, unowned 

 

순환참조가 발생하게 되면 메모리에 계속 남아 있게 됩니다. 

(순환참조에 대해선 추후 다시 정리해 보겠습니다!)

 

이를 보완하기 위해 weak, unowned 키워드를 사용하면 되는데 

이 둘에 대해 알아봅시다. 

 

weak

'약한 참조' 라고 하며, 

인스턴스를 참조할 시, RC를 증가시키지 않습니다.

참조하던 인스턴스가 메모리에서 해제된 경우, 자동으로 nil이 할당되어 메모리가 해제 됩니다. 

 

NOTE

weak을 사용할 때, 둘 중 메모리해제가 더 빨리 되는 프로퍼티에 weak 키워드를 붙여줍니다. 

why?
가리키던 인스턴스가 메모리에서 해제될 경우 nil이 할당 되기 때문에.

 

 

 

unowned

'미소유 참조' 라고 하며,

weak 과 유사하게 unowned 키워드를 붙이게 되면 RC 가 증가 되지 않습니다. 

다만, 이 키워드가 붙은 인스턴스는 참조하고 있는 다른 인스턴스가 메모리에서 해제되기 전까지 먼저 해제되어서는 안됩니다.

 

만약 다른 인스턴스보다 먼저 해제가 된다면 → error 발생 

 


사실 정리를 하긴했는데 아직 unowned의 쓰임새를 정확하게 이해하기가 어렵네요.

살짝 강제 옵셔널해제 할 때와 비슷한 느낌으로 이해했는데 

StackOverFlow에서도 가급적이면 weak을 사용하는걸 권장한다고 합니다.

 

변수가 너무 많고 unowned로 지정해놓은 인스턴스가 꼭 늦게 메모리해제 된다는 보장도 없으니까 그런것 같습니다.

728x90