반응형
모바일 앱을 개발할 때 성능 최적화와 메모리 관리는 필수적인 요소입니다. 성능이 낮거나 메모리 누수가 발생하면 앱이 느려지거나 갑자기 종료될 수 있기 때문입니다. 이번 글에서는 ARC(Automatic Reference Counting)의 개념부터 메모리 릭 탐지 방법, 그리고 Instruments를 활용한 최적화 기법까지 다루어 보겠습니다.
1. ARC(Automatic Reference Counting)란?
iOS에서는 메모리 관리를 자동으로 수행하는 ARC(Automatic Reference Counting)가 도입되어 있습니다. ARC는 객체가 사용되지 않을 때 자동으로 메모리를 해제하여 메모리 릭을 방지합니다.
ARC의 동작 원리
ARC는 객체의 Reference Count(Reference Count)를 기반으로 메모리를 관리합니다.
객체 생성 -> Reference Count 1 증가
객체가 다른 변수에 할당됨 -> Reference Count 증가
변수가 범위를 벗어나거나 nil로 설정됨 -> Reference Count 감소
Reference Count가 0이 되면 ARC가 해당 객체를 메모리에서 해제
강한 참조(Strong Reference)와 약한 참조(Weak Reference)
메모리 릭을 방지하려면 강한 참조 순환(Strong Reference Cycle)을 조심해야 합니다.
1) 강한 참조(Strong Reference)
class Person {
let name: String
init(name: String) {
self.name = name
}
}
var person1: Person? = Person(name: "Alice")
var person2 = person1 // Reference Count 증가
person1 = nil // person1을 해제해도 person2가 참조 중이므로 해제되지 않음
2) 약한 참조(Weak Reference)와 미소유 참조(Unmanaged Reference)
- weak 키워드: Reference Count 증가를 방지하며, 객체가 해제되면 자동으로 nil이 됨.
- unowned 키워드: 객체가 해제될 경우에도 nil이 되지 않으며, 참조하는 객체가 해제된 후 접근하면 크래시 발생.
class Person {
let name: String
weak var friend: Person? // weak 사용으로 순환 참조 방지
init(name: String) {
self.name = name
}
}
2. 메모리 릭 탐지 방법
메모리 릭 = Reference Count가 0이 되지 않아 객체가 메모리에서 해제되지 않는 현상
1) Xcode의 Debug Memory Graph 사용
- Xcode의 Debug Navigator에서 Memory Graph Debugger를 실행하면 현재 앱에서 해제되지 않은 객체를 확인할 수 있습니다.
- 강한 참조 순환(Strong Reference Cycle)이 발생한 객체는 leaks로 표시됩니다.
2) Instruments - Leaks 활용
- Leaks 도구를 사용하면 앱 실행 중 메모리 릭이 있는지 확인할 수 있습니다.
- Profile 실행 후 Leaks를 선택하여 실행하면, 메모리 릭이 발생한 객체를 자동으로 탐지해줍니다.
3. Instruments를 활용한 성능 최적화
1) Time Profiler - CPU 성능 분석
- CPU 사용량을 최적화하는 데 유용합니다.
- 함수 실행 시간을 분석하여 성능 병목이 발생하는 부분을 찾을 수 있습니다.
- 메서드별 실행 시간을 확인하여 불필요한 연산을 최적화할 수 있습니다.
2) Leaks - 메모리 누수 탐지
- 객체가 해제되지 않고 계속 유지되는지 확인할 수 있습니다.
- 메모리 누수가 발생한 지점을 표시하여 빠르게 수정할 수 있습니다.
3) Allocations - 메모리 사용량 분석
- 앱의 전체 메모리 사용량을 확인할 수 있습니다.
- 특정 객체가 너무 많은 메모리를 차지하는 경우, 이를 최적화할 수 있습니다.
4) Energy Log - 배터리 최적화
- 배터리 사용량을 최적화할 수 있습니다.
- CPU, 네트워크, 백그라운드 프로세스가 배터리를 과소비하는지 확인할 수 있습니다.
4. 메모리 최적화를 위한 베스트 프랙티스
- Strong Reference Cycle 방지: weak 또는 unowned 키워드 활용
- 필요 없는 객체 해제: deinit을 활용하여 객체가 해제되는지 확인
- 대용량 데이터 처리 시 주의: 이미지, 동영상 등은 캐싱을 활용
- 불필요한 타이머 해제: Timer는 invalidate() 호출하여 해제
- DispatchQueue 사용 시 주의: self를 weak으로 캡처하여 메모리 릭 방지
dispatchQueue.async { [weak self] in
self?.doSomething()
}
반응형
'클라이언트' 카테고리의 다른 글
[iOS][Swift] iOS Swift에서 사용할 수 있는 암호화 방식 (0) | 2025.02.16 |
---|---|
[iOS] UserDefaults 동작 방식과 보안 (0) | 2025.02.15 |
[Swift] Swift6의 주요 내용 (0) | 2025.02.15 |
[Swift] Swift Concurrency 개념과 사용법 간단 정리 (0) | 2025.02.15 |
[SwiftUI] SwiftUI 성능 최적화: View Rendering을 줄이는 방법 (0) | 2025.02.15 |