Instruments에서 Leaks 및 Allocations 활용
Leaks & Allocations 개념
Leaks: 실행 중인 앱에서 메모리 누수가 발생하는지 감지한는 도구이다. 메모리 할당 후 객체가 해제되지 않고 남아있을 경우 이를 감지할 수 있다.
Allocations: 앱이 실행되면서 메모리가 어떻게 할당되는지 추적하고, 과도한 메모리 사용 여부를 분석하는 도구이다.
Instruments 실행 방법

Xcode에서 Product 창에 Profile 을 선택한다.

그러면 위 사진과 같이 Leaks 가 있는데 그것을 클릭하고 Choose 를 실행하면 실행된다.

이후 실행을 하고 시간이 지났을 때 메모리 누수가 나는 곳을 알려준다.
메모리 누수 예제 코드
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var person: Person? = Person(name: "jon")
var pet: Pet? = Pet(name: "coco")
person?.pet = pet
pet?.owner = person // 순환 참조 발생
person = nil
pet = nil // 메모리에서 해제되지 않음 (메모리 누수 발생)
}
}
class Person {
let name: String
var pet: Pet?
init(name: String) {
self.name = name
print("Person init")
}
deinit {
print("\(name) 해제됨")
}
}
class Pet {
let name: String
var owner: Person?
init(name: String) {
self.name = name
print("Pet init")
}
deinit {
print("\(name) 해제됨")
}
}
이 코드는 기존의 ARC에 대해서 공부할 때 작성했던 코드이다. 이 코드를 실행시키면 메모리 누수가 발생되어 Instruments 의 Leaks 에서 메모리 누수가 발생되는것을 발견할 수 있다.
Heap 메모리 분석 및 메모리 사용량 최적화
Heap 메모리는 앱이 실행되는 동안 동적으로 할당되는 메모리 영역으로 ARC에 의해 관리되지만, 순환참조가 발생하면 메모리 누수 가능성이 있다.
최적화 방법
1. 불필요한 retain 방지
2. autorelease 풀 사용 줄이기
3. lazy 키워드를 활용하여 필요할 때 객체 생성하기
4. 불필요한 대량의 이미지 혹은 데이터 캐싱 줄이기
등의 방식이 존재한다.
예제 코드
class ImageViewController: UIViewController {
var imageView: UIImageView = UIImageView()
var image: UIImage? = UIImage(named: "largeImage")
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = image
}
}
위 예시 코드에서 UIImage(named:) 를 사용하면 캐시가 유지되어 불필요한 메모리 점유가 발생할 수 있다. 이것을 방지하기 위해 아래 코드처럼 파일의 경로를 직접 입력하여 이미지 캐싱을 줄이는 방식도 가능할 수 있다.
class ImageViewController: UIViewController {
var imageView: UIImageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
if let path = Bundle.main.path(forResource: "largeImage", ofType: "png") {
imageView.image = UIImage(contentsOfFile: path)
}
}
}
Run-Time Retain Cycle을 찾는 방법
Retain Cycle 이란 강한 참조가 서로 연결되어 있어 객체가 해제되지 않는 현상을 의미한다. ARC 가 더 이상 객체를 해제할 수 없으므로 메모리 누수가 발생한다.
run-time 에서 retain cycle을 찾으려면 위에서 작성한 Instruments 를 활용해 Leaks 를 실행하여 어느 쪽에서 메모리 누수가 발생하는지 확인하고 그 코드를 수정해야 한다.
Memory Graph Debugger 활용법
Memory Graph Debugger는 힙의 영역에 대한 메모리 스냅샷을 찍어서 보여주는 방식이다.
실행하기 위해서는 앱을 실행한 이후 Debug Memory Graph 를 클릭하면 된다.

저 버튼을 클릭하면 아래의 사진같이 왼쪽 창에서는 현재 생성된 객체들이 나타나고, 오른쪽 창에서는 그 객체들이 가리키는 참조 방향과 함께 연결된 객체들이 나오는것을 확인할 수 있다.
