이미지 목록 성능 최적화 1: Image Decoding

aralc·2021년 10월 26일
1

WWDC 2018 세션 중 Image and Graphics Best Practices에서 이미지 목록의 성능을 최적화할 수 있는 방법이 공유되었는데, 이제 봤어요ㅎㅎ

다음과 같이 두 개의 글로 나누어 정리하려 합니다.
1. 이미지 디코딩 과정에서 메모리는 어떻게 쓰이는가.
2. Downsampling이란?

먼저, 이미지 디코딩 과정에서 메모리가 어떻게 쓰이고 있는지 볼게요.
오류가 있거나 보완해야 할 점은 언제든 피드백 부탁드립니다 🙏


UIImage, UIImageView

UIImage는 하나의 데이터 타입이며, UIImageView는 UIImage를 보여주기 위해 UIKit에서 제공하는 Class이다. 애플의 MVC 구조로 보면 UIImage는 Model, UIImageView는 View이다. UIImage는 이미지를 로드해야하고, UIImageView는 로드된 이미지를 랜더링해서 보여주어야 한다.

이미지를 이미지뷰에 랜더링하는 과정은 일회성 이벤트가 아닌 연속적인 프로세스이다. 그 과정 중 가장 CPU와 메모리를 많이 소모하는 단계가 바로 Decoding이다.

이미지 버퍼의 각 요소는 하나의 픽셀의 색상과 투명도를 가지고 있어서 메모리의 이미지 버퍼 크기는 이미지 크기에 비례한다. 그리고 프레임 버퍼는 실제 어플리케이션의 랜더링된 결과를 보관하고 있다.

APPUIKitFrame BufferDisplay Hardware
view hierarchy 변경앱의 window와 모든 subview를
프레임 버퍼에 랜더링
하드웨어가 보여줄 픽셀당 컬러 정보 제공프레임 버퍼에서 가져온 컨텐츠 노출

APP에 변경이 없으면, 하드웨어는 동일한 데이터를 프레임 버퍼에서 다시 가져온다. APP에서 새로운 이미지를 할당하는 등 뷰 컨텐츠가 변경되면, UIKit은 APP window를 프레임 버퍼에 다시 랜더링한다. 그리고 하드웨어는 프레임 버퍼에서 새로운 컨텐츠를 가져온다.

Image Decoding Process

Data Buffer = Metadata + Encoded Image Data

이미지 파일을 담고 있는 데이터 버퍼는 이미지 크기 정보를 가진 메타데이터와 JPEG 압축 혹은 PNG 형태로 인코딩된 이미지 데이터 자체를 포함한다. 메타데이터의 바이트들은 이미지 픽셀에 대한 정보를 가지고 있지 않다.
1. 이미지 파일을 데이터 버퍼에 담는다.
2. 보여주고자 하는 이미지를 이미지뷰에 할당한다.
3. 이미지뷰를 랜더링하여 프레임 버퍼에 담는다.

4. 프레임 버퍼를 픽셀 당 데이터로 채우기 위해 UIImage는 데이터 버퍼가 담고 있는 이미지와 동일한 크기의 이미지 버퍼를 할당해야 한다.

5. JPEG, PNG 등 인코딩된 이미지 데이터를 픽셀당 이미지 정보로 변환하는 Decoding을 거쳐 이미지 버퍼에 담는다.

6. UIKit이 UIImageView에 랜더링을 요청하면, 이미지 버퍼에서 프레임 버퍼로 이미지 데이터를 복사할 때, UIImageView의 content mode에 따라 scale하여 크기를 조정한다.

디코딩은 이미지가 클 경우 CPU를 많이 소모하기 때문에 UIImageView가 랜더링할 때마다 디코딩을 수행하지 않고, 디코딩된 이미지 데이터가 이미지 버퍼에 보관된다. 때문에 디코딩되는 모든 이미지에 대해 영구적이고 큰 메모리 할당이 필요해질 수 있다. 이 때, 메모리 크기는 이미지 크기에 비례하지만 프레임 버퍼에 실제 랜더링될 이미지 뷰의 크기에 비례할 필요는 없다.

큰 이미지 목록을 불러올 때, 위와 같은 디코딩 과정을 거치면서 APP이 계속해서 메모리 사용량을 축적하면, OS가 개입해 물리적 메모리 영역을 압축하기 시작한다. 이 단계에 CPU가 관여하고, APP 내부의 CPU 사용량과 별개로 CPU 사용량이 증가하게 된다. 결국 APP은 너무 많은 물리적 메모리를 소모하게 되고, OS가 프로세스를 종료시켜야 하는 순간이 올 수 있다. 여기서!! APP에서 사용하는 메모리 양을 줄이기 위해 사용할 수 있는 방법이 downsampling이다.



To be continued...



참조 출처
https://developer.apple.com/videos/play/wwdc2018/219

profile
aralc

0개의 댓글