iOS Memory Deep Dive - 3

ChangJun Lee·2024년 5월 10일
0
post-thumbnail
post-custom-banner

iOS Memory Deep Dive - 3

  • WWDC 18 의 iOS Memory Deep Dive 세션을 정리

Image - 이미지


메모리 사용은 파일의 크기가 아닌, 이미지의 크기와 관련이 있음을 이야기 함

Memory - not the file size

  • 아래 이미지는 크기가 2048 * 1536 이고, 파일 사이즈는 590KB
    그렇다면 실제 메모리는 얼마나 될까?
    Images - file size

  • 10MB 를 사용하게 됨
  • 너비와 높이에 픽셀당 4바이트를 곱하면 약 10MB ...
    Images - Memory Size

  • iOS 에서 이미지가 작동하는 방식은 아래 이미지와 같음
  • Load -> Decode -> Render
    Images - 작동방식 - 1

  • 아까 보여준 이미지를 과정으로 보여주면,
  • Load : 압축된 590KB 의 이미지 파일을 메모리에 로드
  • Decode : 해당 파일을 GPU 가 읽을 수 있도록 변환 -> 압축 해제를 하면서 10MB 의 메모리가 됨
  • Render : 디코딩 된 이미지를 렌더링
    Images - 작동방식 - 2

  • 픽셀당 4바이트를 SRGB 형식으로 얻게 되는데, SRGB 는 가장 일반적인 형식
  • 픽셀당 8비트로 Red, Green, Blue 가 각각 1바이트 그리고 Alpha 요소가 존재 (그림의 최하단 층)
    SRGB Format

  • iOS 하드웨어는 Wide Format 렌더링이 가능
  • Wide Format 은 더 좋은 색상을 얻기 위해, 픽셀당 2바이트가 필요 (크기가 2배)
  • Wide Format 디스플레이가 아닌 경우에 사용하는 것은 유용하지 않음
    Wide format

  • wide 와 반대로 더 작은 형태도 있음
  • 기본 Graysclae 과 Alpha 값만 존재
  • 이 옵션은 Metal 앱 과 같은 Shaders 에서 사용된다고 함 (흔하게 사용되는 경우는 아님)
    Luminance And Alpha 8 format

  • 더 작은 형태도 존재하는데, Alpha 8 이라고 함
  • 픽셀당 1바이트, 1개의 채널만 존재
  • 기본적인 SRGB 보다 75% 작음
  • mask 나, 단색의 텍스트에 적합하다고 함
    Alpha 8 format

그렇다면, 어떤 포맷을 사용하는 것이 좋을까?

How do i pick the right format?

  • 포맷을 선택하지 말고, 포맷이 선택하도록 두라고 말하고 있음
  • UIGraphics BeginImageContext WithOptions 를 사용하지 말라고 하는데,
    항상 4바이트의 SRGB 포맷으로 진행하여 데이터를 낭비할 수 있기 때문..
  • UIGraphics ImageRenderer 를 사용하면 자동으로 최상의 그래픽을 선택
    ( iOS 12 부터 사용 )
    picking right format

  • 아래 이미지에서 UIGraphicsBeginImageContextWithOptions 코드 대신,
    UIGraphicsImageRenderer 를 사용하는 예시를 볼 수 있음
  • 이처럼 사용하면, 픽셀당 1바이트의 데이터를 얻을 수 있음
    UIGraphicsBeginImageContextWithOptionsUIGraphicsImageRenderer

  • 이미지를 다운샘플링 하는 것도 이미지의 용량을 낮추는 방법
    ( 썸네일을 만들 때, 사용하기도 함 )
  • UIImage 를 축소하려는 것은 내부 좌표 변경하게되어 비용이 큼..
    또한, 메모리의 전체 이미지 압축을 풀게 됨
  • 대신, ImageIO 프레임워크가 존재
  • ImageIO 는 이미지를 다운샘플링 할 수 있다면, 이미지의 Dirty Memory 만 할당하도록 함
    downsampling

  • 아래는 디스크에서 파일을 가져오는 코드
  • ImageIO 를 이용한 코드는 이미지가 얼마나 커야 하는지 알려주는 Low Level API 이기 때문에
    몇 가지 파라미터를 제공해주고 난 다음, CGImageSourceCreateThumbnailAtIndex 로 이미지를 생성하도록 요청
    결과는 훨씬 작은 이미지가 나오고, 이전 코드보다 약 50% 더 빠름
    downsampling - bad exampledownsampling - good example

  • 또 하나의 방법으로, 백그라운드 최적화 방법이 있음
  • 일반적으로 foreground 에서는 이미지를 로드하고, 이미지를 보고 있지 않은 경우에는 언로드
  • 앱의 라이프 사이클을 이용, 백그라운드에 진입하는 경우에 이미지를 언로드 할 수 있도록 하는 것도 방법
    backgroundcodecode

profile
iOS Developer
post-custom-banner

0개의 댓글