ARC VS GC

ellyheetov·2021년 10월 6일
1
post-thumbnail

들어가면서

객체의 Life Cycle을 관리하기 위한 방법으로 두가지가 있다.

  • GC(Garbage Collection)
  • ARC(Automatic Reference Counting)

보통 JAVA로 개발하면 GC가 알아서 메모리 관리를 해주기 때문에 순환 참조 같은 문제는 고려할 필요가 없다. 그러나, iOS를 하다보면 순환 참조 문제를 반드시 겪게 된다. 그렇다면 GC랑 ARC가 뭐가 다르길래 순환 참조 문제를 해결할 수 없는 걸까?

Life Cycle Menagement가 뭐야?

한 객체가 메모리에서 얼마나 alive하는지 추적하는 것을 Life Cycle Management 라고 한다.
이를 추적함으로써 더이상 필요하지 않은 객체는 메모리에서 해제시킬 수 있다. 일부 시스템이나 모바일 디바이스 같은 경우 저장소의 용량이 부족하기 때문에 이를 추적하는 것은 꾀나 중요한 일이다. 필요 이상으로 많은 객체가 메모리에 남아있는 경우, Application(심지어 전체 시스템)이 종료 될 수도 있다.

객체의 라이프 사이클 관리가 나오기 이전에는 개발자가 직접 모든 객체의 생명주기를 직접 신경써야 했다. 객체가 필요할 때 생성하고, 다 이용하면 명시적으로 메모리에서 해제(release)해 주어야 했던 것이다. 이것은 코드가 복잡해 질 뿐만 아니라 객체 구조를 유지하기 힘들게 만든다.

GC와 ARC의 목적

GC나 ARC는 모두 개발자의 짐을 덜어주는 데에 목적이 있다. GC나 ARC의 탄생으로 더 이상 참조 카운트를 추적하지 않아도 되었다. 또한, 소유권을 신경쓰지 않아도 되었다. 결과적으로 사용되지 않는 객체를 수동으로 메모리에서 해제 하는 것에 대해 걱정할 필요가 없어진 것이다.

Garbage Collection(GC)

GC란 이미 할당된 메모리에서 더 이상 사용하지 않는 메모리를 해제하는 기술을 말한다. Java에서 사용되고 있는 객체 생명주기 관리 기술이다.

GC는 runtime에 동작하는데, 백그라운드에서 사용되지 않는 객체 및 객체 그래프를 관리한다. GC는 불확실한 간격으로 발생하므로(특정시간이 경과한 후, 혹은 런타임에 사용가능한 메모리가 줄어드는 경우), 객체가 더이상 사용되지 않는 정확한 순간에 반드시 해제 되는 것은 아니다.

Garbage Collection의 장점

  • retain cycle을 포함하여 전체 객체 그래프를 관리할 수 있다.
  • 백그라운드에서 수행되므로, application flow의 메모리 관리 작업이 줄어든다.

Garbage Collection의 단점

  • 백그라운드에서 수행되므로, 객체의 정확한 release 시간을 알 수 없다.
  • GC가 발생하는 경우, application의 다른 스레드가 일시적으로 멈 출 수 있다.

Automatic Reference Counting(ARC)

ARC란 개발자가 기존에 수동으로 개발자가 직접 retain/release를 통해 reference counting을 관리해야하는 부분을 자동으로 관리해는 기술을 말한다.

ARC는 GC와 다른 접근 방식을 취한다. 런타임에 백그라운드에서 사용하지 않는 객체를 찾아 처리하는 대신, 컴파일러가 객체의 참조 회수를 추적하고, 필요에 따라 자동으로 객체를 release하는 코드를 실행 파일에 주입한다.

Automatic Reference Counting의 장점

  • 객체가 사용되지 않을 때, 실시간으로 메모리에서 release한다.
  • 백그라운드 처리가 없으므로, 모바일 디바이스와 같은 저전력(lower-power) 시스템에서 더 효과적이다.

Automatic Reference Counting의 단점

  • retain cycle을 해결할 수 없다.

왜 Retain Cycle을 해결 못해?

순환 참조는 두 개(또는 그 이상)의 객체가 서로를 참조할 때 발생한다. 객체에 대한 외부 참조가 해제 되어도, 서로를 참조하고 있어 alive 상태를 유지하는 현상을 말한다.

GC는 reachable 객체를 살펴 보며 작동한다. 외부 참조가 존재하지 않는 것을 감지하면, 서로를 참조하는 객체 그래프 전체를 버린다. 때문에, 순환 참조문제가 발생하지 않는다.

ARC는 더 낮은 수준에서 작동하고, 참조 수를 기반으로 생명 주기를 관리하기 때문에 retain cycle을 자동으로 처리할 수 없으며, 결과적으로 메모리 누수 문제를 일으킨다.

ARC는 retain cycle을 피하는 방법을 제공 하지만, 개발자의 명시적인 설계가 필요하다. 이를 위해 ARC는 strong, week, unowned와 같은 Storage Modifier를 도입한 것이다.

Storage Modifier는 이 글에서 별도로 다룬다.

정리

  • GC(Garbage Collection)
    • 정기적으로 GC가 동작하여 더 이상 사용되지 않는 메모리를 반환하는 방식, 정확한 시간에 release가 호출되지 않음
    • GC는 runtime에 background에서 메모리를 검사한다.
    • background에서 동작하므로, 앱 성능 저하를 유발한다.
  • ARC(Automatic Reference Counting)
    • RC(Reference Counting)를 통해 메모리를 관리하는 방식
    • compile time에 retain/release 코드를 주입
    • background에서 동작하지 않음, 저전력 시스템에서 효과적

참고

profile
 iOS Developer 좋아하는 것만 해도 부족한 시간

0개의 댓글