[참고]
iOS 앱 개발 과정에서 메모리 관리와 최적화는 매우 중요한 요소이다. 잘못된 메모리 관리는 앱의 성능 저하, UI 지연, 심지어 앱 크래시로 이어질 수 있다.
특히, 이미지나 대용량 데이터 처리가 포함된 앱에서 메모리 최적화는 더욱 중요하다.
iOS 앱 개발에서 메모리 최적화는 성능 향상과 사용자 경험 개선을 위한 중요한 작업이다. Instruments와 같은 도구를 활용해 메모리 사용량을 모니터링하고, lazy loading, ARC 관리, 이미지 최적화 등을 통해 메모리 누수 문제를 해결할 수 있다. 꾸준한 모니터링과 최적화로 앱의 성능을 지속적으로 개선해 나가는 것이 필요하다.
iOS의 메모리 구조와 메모리 최적화 방법에 대해 살펴보고, 이를 효과적으로 모니터링하고 개선할 수 있는 툴인 Instruments를 활용한 메모리 최적화 방법을 알아보자.
iOS 메모리 구조 이해
가상 메모리 (Virtual Memory)
iOS는 가상 메모리 시스템을 사용하여 실제 물리적 메모리(RAM)의 크기에 관계없이 앱이 메모리를 사용할 수 있도록 지원한다. 가상 메모리는 물리 메모리와 디스크 사이에서 데이터가 이동하면서 필요한 메모리 페이지를 관리한다. 즉, iOS는 메모리 부족 상황에서 페이지 아웃(Page-out)을 통해 디스크에 저장하고, 필요할 때 다시 페이지 인(Page-in)으로 가져오는 방식으로 메모리를 효율적으로 사용한다.
메모리 페이지 (Memory Pages)
iOS 메모리는 페이지 단위로 관리된다. 페이지는 크게 두 가지 타입으로 구분된다.
- Clean Pages: 읽기 전용 메모리로 시스템이 자유롭게 제거할 수 있는 메모리
- 예를 들어, 이미 디스크에 저장된 리소스나 코드의 복사본을 보관하는 메모리
- Dirty Pages: 앱이 기록한 정보로, 삭제되면 안 되는 메모리
- 이런 페이지는 메모리 부족 상황에서도 가능한 한 유지되어야 한다.
메모리 누수 (Memory Leaks)
앱이 할당한 메모리를 제대로 해제하지 않으면, 메모리 누수가 발생한다.
메모리 누수가 누적되면 앱의 메모리 사용량이 계속 증가하고, 결국 앱이 크래시될 수 있다. 이는 메모리 최적화에서 가장 주의해야 할 부분 중 하나이다.
Instruments를 통한 메모리 분석
Instruments는 iOS 앱의 성능을 모니터링하고 최적화할 수 있는 강력한 도구이다.
이 도구를 통해 메모리 사용량을 분석하고, 메모리 누수 문제를 찾을 수 있다.
메모리 그래프 (Memory Graph)
메모리 그래프는 앱의 메모리 사용 상태를 시각적으로 보여줍니다. 메모리 그래프를 통해 앱에서 어떤 객체가 메모리에 남아 있는지, 메모리 누수가 발생하는지 확인할 수 있다.
- 메모리 누수 확인: Instruments는 자동으로 메모리 누수를 감지하여 개발자가 놓친 메모리 관리 문제를 쉽게 찾아낼 수 있다
- 객체 참조 주기(Circular References) 분석: 앱에서 객체가 서로를 참조하고 있어 메모리에서 해제되지 않는 상황이 발생할 수 있다. Instruments의 메모리 그래프를 사용하면 이러한 문제를 쉽게 시각적으로 파악할 수 있다.
사용 방법:
- Xcode에서 Instruments 실행: Xcode에서 "Product" > "Profile"을 선택하여 Instruments를 실행
- 메모리 관련 템플릿 선택: "Allocations" 또는 "Leaks" 템플릿을 선택하여 메모리 사용량을 분석한다.
- 실시간 메모리 모니터링: 앱을 실행하면서 메모리 사용량을 실시간으로 확인하고, 누수가 발생하는 시점을 찾아낸다.
메모리 최적화 기법
메모리 최적화는 앱의 성능을 향상시키고, 불필요한 메모리 사용을 줄이는 데 초점을 둔다.
1) 이미지 메모리 최적화
이미지 처리 및 로딩 작업은 메모리 사용량을 기하급수적으로 증가시키는 주요 요인 중 하나이다. 특히, 대용량 이미지나 많은 수의 이미지를 한 번에 로딩하는 경우 메모리 부족 문제가 발생할 수 있다.
- Lazy Loading: 이미지가 화면에 표시될 때만 로드하여 메모리 사용을 줄이는 방식. 스크롤할 때 화면에 표시되는 이미지만 로딩하고, 보이지 않는 이미지는 메모리에서 해제한다.
- 이미지 크기 최적화: 이미지 리소스를 앱의 사용 환경에 맞게 적절한 크기로 줄여 메모리 사용을 최소화한다.
- 캐싱(Caching): 자주 사용되는 이미지는 메모리에 캐싱하여 불필요한 로딩을 방지하되, 메모리 부족 시 적절하게 캐시된 이미지를 해제하도록 관리한다.
2) 메모리 관리 기법
- ARC(Automatic Reference Counting): Swift에서는 자동 참조 카운팅(ARC)을 사용하여 메모리를 자동으로 관리합니다. 하지만, 순환 참조(Circular Reference) 문제가 발생하지 않도록 주의해야 한다. 순환 참조는 객체들 간에 강한 참조가 걸려 있을 때 발생하며, 이는 메모리 누수의 주 원인이 될 수 있다.
- 이를 해결하기 위해 약한 참조(Weak References) 또는 비소유 참조(Unowned References)를 적절히 사용해야 한다.
- Background 작업 분리: 메인 스레드에서 무거운 연산이나 파일 처리를 수행하면 UI가 멈추는 문제가 발생할 수 있다. 이러한 작업은 DispatchQueue.global().async로 백그라운드에서 처리하고, UI 업데이트는 메인 스레드에서 처리해야 한다.
3) 메모리 누수 방지
- 강한 순환 참조 해결: 클로저나 delegate를 사용할 때 강한 참조가 발생하지 않도록 [weak self] 또는 [unowned self]를 사용하여 순환 참조를 방지한다.
- 객체 해제 시점 관리: 사용이 끝난 객체를 즉시 해제하여 메모리를 효율적으로 관리하는 것이 중요하다.
성능 최적화 사례: PDF 변환 작업
문제 상황
370MB 크기의 PDF 파일을 이미지로 변환하여 UI에 표시하는 작업에서 메모리 사용량이 급증하고, 이로 인해 앱의 성능이 저하되었다.
해결 방법
- 백그라운드 처리: PDF를 이미지로 변환하는 작업은 DispatchQueue.global()을 사용하여 백그라운드 스레드에서 처리하고, UI 업데이트는 DispatchQueue.main.async를 사용하여 메인 스레드에서 처리하여 UI 멈춤 현상을 방지했습니다.
- Lazy Loading: 이미지가 화면에 표시될 때만 로딩되도록 하여 메모리 사용량을 줄였다.
- Instruments를 통한 최적화: Instruments를 사용하여 메모리 사용량을 모니터링하고, PDF 변환 과정에서 발생한 메모리 누수 문제를 찾아 해결
성과
최적화 작업 전, PDF 변환 과정에서 CPU 사용량이 약 80%, 메모리 사용량이 약 500MB에 달했으나, 최적화 이후 CPU 사용량을 50% 이하로, 메모리 사용량을 약 300MB로 줄일 수 있었습니다. 또한 UI 딜레이는 약 5초에서 2초로 크게 개선되었다.
'iOS & macOS' 카테고리의 다른 글
UI Delay, UI Freezing (0) | 2024.09.21 |
---|---|
Lazy-loading으로 메모리 관리 및 성능 최적화하기 (3) | 2024.09.21 |
[Swift] Profiling 방법 (0) | 2024.02.20 |
[iOS] NearbyInteraction - NISession이 .finding에서 .found로 넘어가지 않는 문제 해결 (2) | 2024.01.13 |
[macOS] SandBox 환경에서 개발 불가능한 상황 발생 (0) | 2024.01.13 |