일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- playground
- fetchSignInMethods
- Nan
- 회고
- human interface guidelines
- authentication
- retain cycle
- content-type
- YGEnums.h
- arc
- rc
- alamofire
- UITest
- garbage collection
- Automatic Reference Count
- FlexLayout
- App Connect
- Firebase
- Tuist
- Swift
- HealthKit
- layoutSubviews
- ios
- Tuist-Action
- Github-Action
- HIG
- AppStore
- SPM
- pagination
- Xcode
- Today
- Total
멋있게걷는방법
[Swift] GC vs ARC (with. Retain Cycle) 본문
가장 큰 차이는 참조 카운팅 시점.
GC
런타임 중에 메모리 해제 시점을 결정함.
- 이미 할당된 메모리에서 더 이상 사용하지 않는 메모리를 해제하는 기술.
- 런타임에 동작.
- 백그라운드에서 실행.
- 불확실한 간격으로 발생하기 때문에, 객체가 더 이상 사용되지 않는 정확한 순간에 무조건 해제되는 건 아님.
발생시점
각 영역에 할당된 크기의 메모리가 허용치를 넘을 때 수행됨.
⇒ 개발자가 컨트롤할 수 없다.
왜?
⇒ 강제로 GC를 수행시키면 GC를 실행하는 동안 해당 스레드를 제외하고 모든 스레드가 멈춰서 성능에 영향을 줄 수 있다.
성능 저하가 발생할 수 있음.
- 런타임에 계속해서 메모리를 감시하다가 해제하기 때문이다.
순환참조 발생 X
- 계속해서 메모리를 감시하기 때문에 인스턴스가 해제될 가능성이 더 높다.
장점
- retain cycle 관리 가능.
- 백그라운드에서 발생하므로 일반 애플리케이션 흐름의 일부로 수행되는 메모리 작업이 줄어든다. (메모리 성능상 이점)
단점
- 객체의 정확한 release 시점을 알 수 없다.
- 런타임에서 인스턴스를 추적하기 때문에 추적, 해제하는 과정에서 오버헤드가 발생.
ARC
(automatic reference count)
컴파일 시점에 인스턴스 해제 시점이 결정되어 있다.
성능 저하가 발생하지 않음.
- 컴파일 시점에서 인스턴스 해제 시점이 결정되어 있기 때문이다.
순환참조
- 순환참조가 발생하면 인스턴스가 메모리에서 영원히 해제되지 않아, 쌓이게 되면 앱이 터질 수 있음. 개발자의 명시적인 설계가 필요함. 이를 위해 (strong, weak, unowned 같은 걸 도입함.)
장점
- 참조 횟수를 추적해 더 이상 참조되지 않는 인스턴스를 메모리에서 해제한다.
(retain, release를 해 retain count(reference count)가 0이 되면 해제) - 런타임 시점에 추가 리소스가 발생하지 않음. (컴파일 시점에 인스턴스 해제 시점을 결정하기 때문)
- 백그라운드 처리가 없기 때문에 모바일 장치와 같은 저전력 시스템에 더 효율적이다.
단점
- 순환참조 문제
- Retain cycle 자동 처리 불가능. (개발자가 명시적으로 설계해야 함.)
Retain Cycle 자동 처리 불가?
GC는 계속 메모리를 감시한다. 객체에 외부 참조가 존재하지 않는 것을 감지하면, 서로를 참조하는 객체 그래프 전체를 버린다. 때문에 순환참조가 발생하지 않음.
근데, ARC는. 참조 수를 기반으로 생명 주기를 관리한다. 때문에 retain cycle을 자동으로 처리할 수 없고, 결과적으로 순환참조가 발생할 수 있음.
외부 참조가 없다?
만약 이런 상황일 때,
두 인스턴스가 해제(nil) 된다면? (외부 참조가 없어진다면)
프로퍼티인 child만 남게 되는데 이 둘은 해제되지 않고 영원히 해제되지 않고 남아있게 된다.
ARC의 경우에는
var a = A()
var b = B()
객체를 생성할 때 retain(+1) 되면서 Retain Count(reference count)가 +1 되고, (현재 1)
a.child = b
b.child = a
다른 인스턴스를 대입할 때 또 +1 되면서 Retain Count(reference count)가 +1 된다. (현재 2)
인스턴스를 nil로 바꾸면서 release(-1) 되면서 Retain Count(reference count)가 1이 된다. (현재 1)
Retain Count(reference count)가 0이 될 때 메모리가 전부 해제되니까. 순환참조 발생.
중요!!!
그니까 GC는 이런 상황일 때 참조 객체 그래프 전체를 버려버리니까 순환참조가 발생하지 않고,
ARC는 참조수로 생명 주기를 관리하기 때문에 순환참조가 발생하는 것. → 때문에 weak, unkowned로 관리하는 것.
'iOS' 카테고리의 다른 글
[Swift] Override함수에서 Super는 필수일까? (with. layoutSubViews) (0) | 2023.07.02 |
---|---|
App Store 배포 리젝 사유 회고 2.1 , 1.2 (0) | 2023.06.27 |
App Store 배포 회고(with. 개발 & 책임) (0) | 2023.06.25 |
[Swift] 지금 바로 Pagination 을 적용해야 하는 이유 (0) | 2023.06.08 |
[Swift] firebase - 이메일 중복 검사 (0) | 2023.04.12 |