본문 바로가기
iOS & macOS

메모리 최적화 - iOS Memory Deep Dive

by Bokoo14 2024. 2. 23.

[참고]

더보기

https://ios-daniel-yang.tistory.com/96#google_vignette

 

[Swift/TIL #20] 이미지 메모리 최적화 방법들 (WWDC 18)

[TIL #20] 2023 / 05 / 01 앨범에서 이미지를 불러오는 작업을 하는데, 사진을 추가할 때마다 메모리 사용량이 기하급수적으로 증가하더라고요. 그래서 오늘은 간단히 이미지 관련, 메모리 최적화 방

ios-daniel-yang.tistory.com

https://hucet.tistory.com/38

 

[WWDC 2018] iOS Memory Deep Dive (1/2)

WWDC 2018 iOS Memory Deep Dive 를 정리한 포스트입니다. 더 자세한 내용을 원하시면 위 링크를 참조하시길 바랍니다. Virtual Memory? Device마다 RAM의 크기는 다르며, 서로 다른 RAM 시스템을 통일된 Adress 시

hucet.tistory.com

https://codingmon.tistory.com/36

 

[WWDC18] iOS memory deep dive - 1

메모리 사용량을 왜 줄일까 더 나은 사용자 경험 더 빠른 앱 실행 시스템 성능 향상 앱이 메모리에 더 오래 유지된다 (이건 뭘까) etc Memory pages 힙에 여러개의 객체들을 담을 수 있다 Page Type Clean:

codingmon.tistory.com

https://postpress.info/entry/iOS-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%82%AC%EC%9A%A9%EB%9F%89-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0

 

iOS 메모리 사용량 파헤치기

앱 메모리 사용량 줄이기 앱 메모리 사용량을 줄여야 하는 이유: 사용자가 더 나은 경험을 할 수 있다는 것입니다. 앱 실행 속도가 빨라질 뿐만 아니라 시스템이 더 잘 수행될 것입니다. 앱이 메

postpress.info

https://medium.com/@sylpid003/swift-xcode-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B7%B8%EB%9E%98%ED%94%84-%EB%B6%84%EC%84%9D-tca-project-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%88%84%EC%88%98-%ED%95%B4%EA%B2%B0-c11580e1b30b

 

Swift: Xcode 메모리 그래프 분석 & TCA Project 메모리 누수 해결

instruments, terminal 로 메모리 누수를 분석하고 문제를 해결해 보자.

medium.com

 

 

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의 메모리 그래프를 사용하면 이러한 문제를 쉽게 시각적으로 파악할 수 있다.

사용 방법:

  1. Xcode에서 Instruments 실행: Xcode에서 "Product" > "Profile"을 선택하여 Instruments를 실행
  2. 메모리 관련 템플릿 선택: "Allocations" 또는 "Leaks" 템플릿을 선택하여 메모리 사용량을 분석한다.
  3. 실시간 메모리 모니터링: 앱을 실행하면서 메모리 사용량을 실시간으로 확인하고, 누수가 발생하는 시점을 찾아낸다.

메모리 최적화 기법

메모리 최적화는 앱의 성능을 향상시키고, 불필요한 메모리 사용을 줄이는 데 초점을 둔다.

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초로 크게 개선되었다.