Memory Debugging
ios에선 메모리 관리를 유의해야 한다. 특히 ARC를 사용한 메모리 자동 참조/해제를 하기 때문에 컴파일 타임때 효과적인 메모리 관리를 할순 있지만 retain cycle에 의한 해제되지 못한 메모리들은 앱에 계속 남아있어 메모리누수가 발생할 수 있다.
Xcode에서 메모리를 분석할 수 있는 여러 방식들이 있다.
Xcode Memory Graph Debugger
현재 사용중인 memory에 대해 Footprint를 확인할 수 있다.
앱의 전체 메모리 사이즈에 대한 그래프를 실시간으로 확인할 수 있다.
하단의 debug memory graph버튼을 클릭해 memory graph도 확인할 수 있다.
왼쪽에서 현재 메모리에 포함되어 있는 객체들과 해당 클래스의 인스터스 및 주소를 확인할 수 있다.
memory graph에서 굵고 진한선은 객체간 강한참조(strong reference)를 이루고있고
회색의 선은 객체간 약한참조(weak reference)를 구성하는것을 확인할 수 있다.
Memory Snapshot(Command Line)
memory graph debugger중 Xcode상단의 File -> Export Memory Graph를 누르면 현재 메모리상태를 스냅샷으로 저장할 수 있다.
vmmap명령어를 사용하여 저장한 memory snapshot파일을 확인할 수 있다.
VIRTUAL SIZE: 앱이 원하는 모든 메모리
RESIDENT SIZE: 실제 메모리에 로드되는 메모리
DIRTY SIZE: 앱에 할당한 메모리
SWAPPED SIZE: Compressed Size를 의미하며 Memory Compressor에 압축되기 전 Size
Memory Leak Example
실제로 예제로 Memory Leak을 발생한뒤 Memory를 분석해보자.
ViewController와 SecondViewController를 만들고 Next버튼을 누르면 ViewController -> SecondViewController로 push되도록 설정
SecondViewController에서 MockView의 delegate를 강한참조되도록 설정하여 MockView와 retainCycle이 이뤄지도록 설정
protocol DefaultDelegate {
func delegateMethod()
}
class MockView: UIView {
var delegate: DefaultDelegate?
}
class SecondViewController: ViewController {
override func viewDidLoad() {
super.viewDidLoad()
let mockView = MockView()
// strong reference
mockView.delegate = self
view.addSubview(mockView)
}
}
extension SecondViewController: DefaultDelegate {
func delegateMethod() {
print("delegate implementation")
}
}
SecondViewController를 계속 띄웠다 반복하고 Memory graph를 확인해보자.
약 20번정도 반복하고 memory Use의 사용량은 위와같이 증가하였고
MockView의 메모리 인스턴스가 해제되지 않고 남아있는것을 볼 수 있다.
위의 메모리 leak을 해결하기 위해 MockView의 delegate를 약한참조가 되도록 설정해보자.
...
class MockView: UIView {
weak var delegate: DefaultDelegate?
}
...
SecondViewController가 MockView의 delegate를 약하게 참조하고 있으므로 SecondViewController가 해제될때 메모리에 남아있지 않고 같이 해제된다.
여러번 반복했을때 Memory graph에서 MockView의 인스턴스가 해제되었음을 확인할 수 있다.
참고:
'swift' 카테고리의 다른 글
Tuist로 프로젝트 관리해보기 (0) | 2022.03.05 |
---|---|
The Composable Architecture(TCA) (0) | 2022.03.02 |
DispatchSemaphore (0) | 2022.02.06 |
UICollectionView Custom Layout (0) | 2022.02.03 |
Dynamic Cell Size CollectionView (0) | 2022.01.25 |