λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
🍎 iOS/WWDC

[WWDC18] iOS Memory Deep Dive

by Danna 2022. 11. 27.
728x90
728x90
 

iOS Memory Deep Dive - WWDC18 - Videos - Apple Developer

Discover how memory graphs can be used to get a close up look at what is contributing to an app's memory footprint. Understand the true...

developer.apple.com

[WWDC18] iOS Memory Deep Dive

  • Why reduce memory :: μ™œ λ©”λͺ¨λ¦¬λ₯Ό 쀄여야 ν•˜λŠ”μ§€?
  • Memory footprint :: λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ— λŒ€ν•œ 이둠적인 이야기
  • Tools for profiling footprint :: λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ„ 확인할 수 μžˆλŠ” 툴 μ†Œκ°œ
  • Images :: λ©”λͺ¨λ¦¬λ₯Ό 많이 μ‚¬μš©ν•˜λŠ” 이미지에 λŒ€ν•˜μ—¬
  • Optimizing when in background :: λ°±κ·ΈλΌμš΄λ“œμ—μ„œμ˜ 이미지 λ©”λͺ¨λ¦¬ 졜적
  • Demo 

🧐 Why reduce memory

λ©”λͺ¨λ¦¬λ₯Ό μ€„μ΄λŠ” μ΄μœ λŠ” λ¬΄μ—‡μΌκΉŒ?

  • μœ μ €κ°€ 더 λ‚˜μ€ κ²½ν—˜μ„ ν•  수 있기 λ•Œλ¬Έμ΄λ‹€! (이것이 고객 쀑심..?πŸ₯Ή)
  • μ•± μ‹€ν–‰ 속도가 빨라지고, μ‹œμŠ€ν…œμ΄ 잘 μˆ˜ν–‰λ˜κ³ , 앱이 λ©”λͺ¨λ¦¬μ— 더 였래 μœ μ§€λ  수 μžˆλŠ” λ“± λ‹€μ–‘ν•œ κ΄€μ μ—μ„œ μž₯점이 μžˆλ‹€.

λ©”λͺ¨λ¦¬λ₯Ό μ€„μ΄λŠ” 것에 λŒ€ν•΄ μ΄μ•ΌκΈ°ν•˜μ§€λ§Œ μ‹€μ œλ‘œλŠ” memory footprint 에 λŒ€ν•œ 이야기이닀.

 

πŸ’‘ footprint : νŠΉμ • ν•˜λ“œμ›¨μ–΄λ‚˜ μ†Œν”„νŠΈμ›¨μ–΄κ°€ μ°¨μ§€ν•˜κ³  μžˆλŠ” κ³΅κ°„μ˜ 크기
ν•˜λ“œμ›¨μ–΄μ˜ κ²½μš°μ—λŠ” 물리적인 곡간, μ†Œν”„νŠΈμ›¨μ–΄μ—μ„œλŠ” λ©”λͺ¨λ¦¬ 곡간을 의미
memory footprint 
: μ†Œν”„νŠΈμ›¨μ–΄κ°€ μ°¨μ§€ν•˜λŠ” λ©”λͺ¨λ¦¬μ˜ 크기 즉 λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ 을 μ˜λ―Έν•œλ‹€.

 

🐾 Memory Footprint

λͺ¨λ“  λ©”λͺ¨λ¦¬κ°€ λ™μΌν•˜κ²Œ μƒμ„±λ˜λŠ” 것은 μ•„λ‹ˆλ‹€.

  • νŽ˜μ΄μ§€μ— λŒ€ν•΄ 이야기 ν•΄μ•Όν•œλ‹€.

μš”λŸ° νŽ˜μ΄μ§€κ°€ μ•„λ‹ˆλΌ, λ©”λͺ¨λ¦¬μ˜ νŽ˜μ΄μ§€ λ‹¨μœ„μ— λŒ€ν•΄ μ•Œμ•„μ•Ό ν•œλ‹€.

  • λ©”λͺ¨λ¦¬ νŽ˜μ΄μ§€λŠ” μ‹œμŠ€ν…œμ— μ˜ν•΄ 제곡되고, νž™μ— μ—¬λŸ¬ 개체λ₯Ό μ €μž₯ν•  수 μžˆλ‹€.
  • 그림의 Data 처럼 μ—¬λŸ¬ νŽ˜μ΄μ§€μ— 걸쳐 μžˆμ„ μˆ˜λ„ μžˆλ‹€.

  • Page λ‹¨μœ„μ˜ ν¬κΈ°λŠ” 일반적으둜 16KB 이닀.
    • Page type clean, dirty ??  πŸ€” λŠ” μ•„λž˜μ—μ„œ 더 μ‚΄νŽ΄λ΄…λ‹ˆλ‹€!
  • μ•±μ˜ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ€ νŽ˜μ΄μ§€μˆ˜ * νŽ˜μ΄μ§€ 크기둜 계산할 수 μžˆλ‹€.

πŸ“„ Clean and dirty pages 예제

20,000개의 μ •μˆ˜ 배열을 ν• λ‹Ήν•˜λŠ” μ˜ˆμ‹œ

  • μ‹œμŠ€ν…œμ€ 6개의 νŽ˜μ΄μ§€λ₯Ό μ€€λ‹€.
  • 처음 ν• λ‹Ήν•  λ•Œμ— νŽ˜μ΄μ§€λ“€μ€ clean μƒνƒœμ΄λ‹€.

  • 데이터 버퍼에 값을 μ“°κ²Œ 되면, ν•΄λ‹Ή 값이 μžˆλŠ” νŽ˜μ΄μ§€λŠ” dirty μƒνƒœκ°€ λœλ‹€.
  • μ²«λ²ˆμ§Έμ™€ λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€ 사이에 μžˆλŠ” νŽ˜μ΄μ§€λ“€μ€ clean μƒνƒœμ΄λ‹€.
  • clean page λΌλŠ” 건 μ‹œμŠ€ν…œμœΌλ‘œλΆ€ν„° νŽ˜μ΄μ§€λ₯Ό ν• λ‹Ήλ°›μ§€λ§Œ 값이 쓰여지지 μ•Šμ€ μƒνƒœ, dirty page λŠ” νŠΉμ • 값을 써 졜초의 ν• λ‹Ήλœ μƒνƒœκ°€ μ•„λ‹Œ κ±Έ μ˜λ―Έν•˜λŠ”λ“― ν•˜λ‹€!

πŸ“ Memory mapped files

  • 또 ν•˜λ‚˜ μ•Œμ•„μ•Ό ν•  것은 λ©”λͺ¨λ¦¬ 맀핑 파일,
  • λ©”λͺ¨λ¦¬ 맀핑 νŒŒμΌμ€ λ””μŠ€ν¬μ— μžˆμ§€λ§Œ λ©”λͺ¨λ¦¬μ— λ‘œλ“œλœ νŒŒμΌμ„ μ˜λ―Έν•œλ‹€.
  • 읽기 μ „μš© νŒŒμΌμ€ 항상 clean page 이닀.
  • 컀널은 파일이 Disk μ—μ„œ RAM 으둜 λ“€μ–΄μ˜€κ³  λ‚˜κ°€λŠ” μ‹œκ°„μ„ κ΄€λ¦¬ν•œλ‹€.

πŸ–Ό JPEG 이미지 νŒŒμΌμ„ 톡해 μ˜ˆμ‹œλ₯Ό λ“€μ–΄λ³Όκ²Œμš”

  • 50KB 크기의 JPEG μ΄λ―Έμ§€μ˜ 경우, λ©”λͺ¨λ¦¬ λ§€ν•‘μ‹œ 4νŽ˜μ΄μ§€μ˜ λ©”λͺ¨λ¦¬μ— λ§€ν•‘λœλ‹€.
  • 1νŽ˜μ΄μ§€λ‹Ή 16KB, 4νŽ˜μ΄μ§€ 64KB 둜, 14KB 의 μ—¬μœ  λ©”λͺ¨λ¦¬κ°€ μžˆλ‹€.
  • λ„€λ²ˆμ§Έ νŽ˜μ΄μ§€λŠ” μ™„μ „νžˆ μ±„μ›Œμ§€μ§€ μ•Šμ•„ λ‹€λ₯Έ μš©λ„λ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
  • μ™„μ „νžˆ μ±„μ›Œμ§„ μ„Έκ°œμ˜ νŽ˜μ΄μ§€λŠ” 항상 μ‹œμŠ€ν…œμ—μ„œ μ œκ±°ν•  수 μžˆμ§€λ§Œ, λ„€λ²ˆμ§Έ νŽ˜μ΄μ§€λŠ” λ‹€λ₯Έ μš©λ„λ‘œ μ‚¬μš©λ  경우 λ°”λ‘œ μ œκ±°ν•  수 μ—†λŠ”κ±ΈκΉŒμš”? πŸ€”

Typical app memory profile

μΌλ°˜μ μž… μ•±μ—μ„œ λ©”λͺ¨λ¦¬ ν’‹ν”„λ¦°νŠΈμ™€ ν”„λ‘œνŒŒμΌμ˜ λ©”λͺ¨λ¦¬ μ„Έκ·Έλ¨ΌνŠΈλŠ” dirty, compressed, clean 둜 λ‚˜λ‰˜μ–΄μ§„λ‹€.

clean memory

clean memory λŠ” νŽ˜μ΄μ§€ 아웃할 수 μžˆλŠ” 데이터λ₯Ό μ˜λ―Έν•œλ‹€. (λ©”λͺ¨λ¦¬ ν• λ‹Ή ν•΄μ œκ°€ κ°€λŠ₯ν•œ?)

  • Memory mapped file 을 μ˜λ―Έν•œλ‹€.
  • 이미지, 데이터 λΈ”λž(Blob, Binary Large Object), ν•™μŠ΅ λͺ¨λΈ
    • Blob,, 이미지, λΉ„λ””μ˜€, μ‚¬μš΄λ“œ λ“±κ³Ό 같은 λ©€ν‹°λ―Έλ””μ–΄ 객체λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ μžλ£Œν˜•, Large Object의 μœ„μΉ˜ 포인터λ₯Ό μ €μž₯ν•œλ‹€.
  • ν”„λ ˆμž„μ›Œν¬κ°€ 될 μˆ˜λ„ μžˆλ‹€.
    • λͺ¨λ“  ν”„λ ˆμž„μ›Œν¬μ—λŠ” DATA CONST μ„Ήμ…˜μ΄ 있고, μΌλ°˜μ μœΌλ‘œλŠ” clean memory 에 μ†ν•˜μ§€λ§Œ swizzling 을 ν†΅ν•˜λ©΄ dirty memory κ°€ 될 μˆ˜λ„ μžˆλ‹€.

Dirty memory

Dirty memory λŠ” μ•±μ—μ„œ 값을 μ“΄ λ©”λͺ¨λ¦¬λ₯Ό μ˜λ―Έν•œλ‹€.

  • λ¬Έμžμ—΄, λ°°μ—΄ λ“± λ™μ μœΌλ‘œ ν• λ‹Ήλœ λͺ¨λ“  객체
  • 이미지 버퍼λ₯Ό λ””μ½”λ”© ν•˜λŠ” 경우
  • ν”„λ ˆμž„μ›Œν¬ 쀑 데이터 μ„Ήμ…˜κ³Ό 데이터 더티 μ„Ήμ…˜μ΄ 이에 μ†ν•œλ‹€.

πŸ— Frameworks

  • ν”„λ ˆμž„μ›Œν¬μ—λŠ” clean memory 에 μ†ν•˜λŠ” μ˜μ—­κ³Ό dirty memory 에 μ†ν•˜λŠ” μ˜μ—­μ΄ λ‘˜ λ‹€ μ‘΄μž¬ν•œλ‹€.
  • ν”„λ ˆμž„μ›Œν¬λ₯Ό 자체적으둜 μœ μ§€ν•˜κ³  κ΄€λ¦¬ν•œλ‹€λ©΄, 싱글톀과 μ „μ—­ μƒμ„±μžλŠ” dirty memory λ₯Ό μ€„μ΄λŠ”λ° 쒋은 방법이 될 것이닀.
    • 싱글톀은 μƒμ„±λœ 이후 항상 λ©”λͺ¨λ¦¬μ— μ‚΄μ•„ 있고,
    • μƒμ„±μž λ˜ν•œ ν”„λ ˆμž„μ›Œν¬λ₯Ό λ§ν‚Ήν•˜κ±°λ‚˜ ν΄λž˜μŠ€κ°€ λ‘œλ“œλ  λ•Œλ§ˆλ‹€ 싀행될 것이닀.

πŸ—³ Compressed memory (μ••μΆ• λ©”λͺ¨λ¦¬)

iOS μ—λŠ” 전톡적인 λ””μŠ€ν¬ μŠ€μ™‘ μ‹œμŠ€ν…œμ΄ μ—†λŠ” λŒ€μ‹ , λ©”λͺ¨λ¦¬ μ••μΆ•κΈ° (Memory compressor) λ₯Ό μ‚¬μš©ν•œλ‹€. iOS 7 μ—μ„œ λ„μž… λ˜μ—ˆλ‹€.

  • memory compressor λŠ” μ••μΆ•, μ••μΆ• ν•΄μ œλ₯Ό μˆ˜ν–‰ν•œλ‹€.
  • μ ‘κ·Όλ˜μ§€ μ•Šμ€ νŽ˜μ΄μ§€λ₯Ό 가져와 μ••μΆ•ν•΄μ„œ, 더 λ§Žμ€ 곡간을 λ§Œλ“ λ‹€.
  • λ‹€μ‹œ μ ‘κ·Όν•  경우 λ©”λͺ¨λ¦¬λ₯Ό 읽을 수 μžˆλ„λ‘ 압좕을 ν•΄μ œν•œλ‹€.

캐싱에 μ‚¬μš©λ˜λŠ” dictionary λ₯Ό μ˜ˆμ‹œλ‘œ λ“€μ–΄λ΄…λ‹ˆλ‹€ πŸ“”

  • μ„Έ 개 νŽ˜μ΄μ§€μ˜ λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ§€λ§Œ, ν•œλ™μ•ˆ μ‚¬μš©ν•˜μ§€ μ•Šκ³  μ‹œμŠ€ν…œμ— λ©”λͺ¨λ¦¬ 곡간이 ν•„μš”ν•˜λ‹€λ©΄ ν•œ νŽ˜μ΄μ§€λ‘œ 압좕될 수 μžˆλ‹€.
  • ν˜„μž¬ 압좕이 λ˜μ–΄ ν•œ νŽ˜μ΄μ§€λ‘œ λ©”λͺ¨λ¦¬ μ ˆμ•½μ„ ν•˜κ³  μžˆμ§€λ§Œ, μ‹€μ œλ‘œ μ ‘κ·Όν•  μ‹œμ μ—λŠ” λ‹€μ‹œ μ„Έ νŽ˜μ΄μ§€λ₯Ό μ‚¬μš©ν•˜κ²Œ 될 것이닀.

⚠ Memory warnings

앱이 항상 λ©”λͺ¨λ¦¬ 경고의 원인은 μ•„λ‹ˆλ‹€.

  • λ©”λͺ¨λ¦¬κ°€ λΆ€μ‘±ν•œ λ””λ°”μ΄μŠ€λ₯Ό μ‚¬μš©μ€‘μ— μ „ν™”λ₯Ό λ°›μœΌλ©΄ λ©”λͺ¨λ¦¬ κ²½κ³ κ°€ λ°œμƒν•  수 있고, κ·Έλ•Œ 앱이 μ’…λ£Œλ  수 μžˆλ‹€.
  • λ©”λͺ¨λ¦¬ μ••μΆ•κΈ°λ₯Ό 톡해 μ••μΆ•λœ 경우, μ‹€μ œλ‘œλŠ” λ©”λͺ¨λ¦¬λ₯Ό 더 μ“Έ 수 있기 λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬ ν•΄μ œλ₯Ό 더 λ³΅μž‘ν•˜κ²Œ λ§Œλ“ λ‹€.
  • λ©”λͺ¨λ¦¬ κ²½κ³ κ°€ λ°œμƒν•  λ•Œ 캐싱을 ν•˜μ§€ μ•Šκ±°λ‚˜ λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ„ μ‘°μ •ν•˜λŠ” λ“±μ˜ μ •μ±… 변경을 ꢌμž₯ν•œλ‹€.

λ©”λͺ¨λ¦¬ κ²½κ³ μ‹œ μ•±μ—μ„œ μˆ˜ν–‰ν•  수 μžˆλŠ” λ™μž‘μœΌλ‘œ, μΊμ‹œμ—μ„œ λͺ¨λ“  객체λ₯Ό μ œκ±°ν•˜κΈ°λ‘œ κ²°μ •ν–ˆλ‹€κ³  ν•©μ‹œλ‹€ πŸ€”

μ•„κΉŒ μ••μΆ•ν–ˆλ˜ 캐싱을 μœ„ν•œ λ”•μ…”λ„ˆλ¦¬μ— μ•‘μ„ΈμŠ€ν•˜κΈ° λ•Œλ¬Έμ— 더 λ§Žμ€ νŽ˜μ΄μ§€λ₯Ό μ‚¬μš©ν•˜κ²Œ λœλ‹€.

  • λ©”λͺ¨λ¦¬κ°€ μ œν•œλ˜μ–΄ μžˆλŠ” ν™˜κ²½μ—μ„œλŠ” μ μ ˆν•˜μ§€ μ•Šλ‹€ πŸ€”
  • μΊμ‹±λœ κ°œμ²΄λ“€μ„ μ œκ±°ν•΄ ν•œνŽ˜μ΄μ§€λ‘œ 돌리기 μœ„ν•΄, 이미 μ••μΆ•λ˜μ–΄ ν•œνŽ˜μ΄μ§€λ‘œ μœ μ§€λ˜μ–΄ μžˆλŠ” μƒνƒœλ₯Ό ν’€μ–΄ 투머치 μž‘μ—…μ„ ν•˜κ²Œ λœλ‹€.

λ©”λͺ¨λ¦¬ κ΄€μ μ—μ„œ 캐싱에 λŒ€ν•΄ μ€‘μš”ν•œ 것듀이 μžˆλ‹€.

  • βš–οΈ CPU 와 λ©”λͺ¨λ¦¬ μ‚¬μš©μ˜ νŠΈλ ˆμ΄λ“œ μ˜€ν”„λ₯Ό μƒκ°ν•˜μž.
    • 캐싱을 ν•  λ•Œ CPU κ°€ 반볡적인 μž‘μ—…μ„ ν•˜μ§€ μ•Šκ²Œ λ…Έλ ₯ν•˜μ§€λ§Œ, 캐싱을 λ„ˆλ¬΄ 많이 ν•˜κ²Œλ˜λ©΄ λ©”λͺ¨λ¦¬λ₯Ό 많이 μ‚¬μš©ν•΄ μ‹œμŠ€ν…œμ— λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€.
  • λ©”λͺ¨λ¦¬ 압좕기와 μΊμ‹œκ°€ μžˆλŠ”κ±Έ κΈ°μ–΅ν•˜κ³ , λ”•μ…”λ„ˆλ¦¬ λŒ€μ‹ μ— NSCache λ₯Ό μ‚¬μš©ν•˜λŠ”κ²Œ μ•ˆμ „ν•˜λ‹€.
    • NSCache λŠ” λ©”λͺ¨λ¦¬κ°€ λΆ€μ‘±ν•  λ•Œ μžλ™μœΌλ‘œ μΊμ‹±λœ κ²ƒμ˜ 일뢀λ₯Ό ν•΄μ œν•˜λ„λ‘ λ™μž‘ν•œλ‹€.

πŸ“ Typical app memory profile

일반적으둜 μ•±μ—μ„œ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ (footprint) 에 λŒ€ν•΄ 이야기 ν•  λ•Œμ—λŠ” dirty, compressed μ„Έκ·Έλ¨ΌνŠΈλ₯Ό μ˜λ―Έν•œλ‹€. clean memory μ˜μ—­μ€ 크게 μ€‘μš”ν•˜μ§€ μ•Šλ‹€.

  • λͺ¨λ“  μ•±μ—λŠ” μ‚¬μš© κ°€λŠ₯ν•œ λ©”λͺ¨λ¦¬ μ œν•œμ΄ μžˆλ‹€.
  • λ©”λͺ¨λ¦¬ μ œν•œμ€ λ””λ°”μ΄μŠ€λ§ˆλ‹€ λ‹¬λΌμ§ˆ 수 μžˆλ‹€.
  • μ•±λ§ˆλ‹€ μ œν•œλ˜λŠ” λ©”λͺ¨λ¦¬λŠ” 생각보닀 많이 ν• λ‹Ήλœλ‹€.
  • λ©”λͺ¨λ¦¬ 곡간을 ν™•μž₯ν•  수 μžˆμ§€λ§Œ, 이 곡간은 적기 λ•Œλ¬Έμ— μ£Όμ˜ν•΄μ•Ό ν•œλ‹€.
  • 앱에 ν• λ‹Ήλœ λ©”λͺ¨λ¦¬ 곡간을 μ΄ˆκ³Όν•˜λ©΄ exception 이 λ°œμƒν•œλ‹€.

Tools for Profiling Footprint

  • μ•±μ˜ footprint λ₯Ό ν”„λ‘œνŒŒμΌλ§ ν•  수 μžˆλŠ” 도ꡬλ₯Ό μ†Œκ°œν•©λ‹ˆλ‹€.
  • Xcode memory gauge λŠ” λ””λ²„κΉ…μ‹œ μ•±μ˜ λ©”λͺ¨λ¦¬ 곡간을 λΉ λ₯΄κ²Œ λ³Ό 수 μžˆλ‹€.

Instruments λŠ” μ•±μ˜ λ©”λͺ¨λ¦¬ 곡간을 ν™•μΈν•˜κΈ° μœ„ν•œ μ—¬λŸ¬κ°€μ§€ 방법을 μ œκ³΅ν•œλ‹€.

  • Allocations : μ•±μ—μ„œ μƒμ„±ν•œ νž™ 할당을 ν”„λ‘œνŒŒμΌλ§
  • Leaks : μ‹œκ°„μ΄ 지남에 λ”°λ₯Έ ν”„λ‘œμ„ΈμŠ€μ˜ λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ₯Ό 확인
  • VM Tracker : dirty, compressed memory λ₯Ό ν”„λ‘œνŒŒμΌλ§ ν•˜λŠ” 방법을 제곡
    • μ••μΆ• λ©”λͺ¨λ¦¬μΈ dirty size, swapped size, resident size λ₯Ό μ•Œλ €μ€€λ‹€.
  • Virtual memory trace : μ•±κ³Ό κ΄€λ ¨λœ 가상 λ©”λͺ¨λ¦¬ μ‹œμŠ€ν…œμ˜ μ„±λŠ₯을 μ•Œ 수 μžˆλ‹€
    • By Operation νƒ­μ—μ„œ VM ν”„λ‘œνŒŒμΌμ„ μ œκ³΅ν•΄ page cache hits, page zero fills λ₯Ό λ³Ό 수 μžˆλ‹€.

memory resource exceptions

  • Xcode 10 λΆ€ν„°λŠ” ν•΄λ‹Ή EXC exception 을 μΊμΉ˜ν•΄μ„œ 앱을 μΌμ‹œ μ€‘μ§€ν•œλ‹€.
  • ν•΄λ‹Ή μ‹œμ λΆ€ν„° λ©”λͺ¨λ¦¬ 디버거λ₯Ό λΆ™μ—¬ 확인할 수 μžˆλ‹€.

Xcode λ©”λͺ¨λ¦¬ λ””λ²„κ±°λŠ” Xcode 8λΆ€ν„° μ œκ³΅λ˜μ–΄, 객체간 λ””νŽœλ˜μ‹œ, 사이클, λˆ„μˆ˜(leak)λ₯Ό 좔적할 수 μžˆλ‹€.

  • κ·Έλž˜ν”„ ν˜•νƒœλ‘œ λ‚˜νƒ€λ‚œκ±΄ Xcode 10 뢀터라고 ν•©λ‹ˆλ‹€ πŸ˜‡
  • Xcode λ‚΄λΆ€μ μœΌλ‘œ Memgraph 파일 ν˜•μ‹μ„ μ‚¬μš©ν•΄ λ©”λͺ¨λ¦¬ 정보λ₯Ό μ €μž₯ν•œλ‹€.
  • Memgraph λ₯Ό export ν•΄μ„œ command line tool μ—μ„œ 확인할 μˆ˜λ„ μžˆλ‹€.

vmmap

λ©”λͺ¨λ¦¬ λ¦¬μ†ŒμŠ€ μ˜ˆμ™Έκ°€ λ°œμƒν•œ μƒνƒœμ˜ Memgraph λŠ” μ»€λ§¨λ“œ 라인 λͺ…령어인 vmmap 을 μ΄μš©ν•΄μ„œ 뢄석할 수 μžˆλ‹€.

  • vmmap 은 ν”„λ‘œμ„ΈμŠ€μ— ν• λ‹Ήλœ 가상 λ©”λͺ¨λ¦¬ μ˜μ—­μ„ 보여쀀닀.

vmmap --summary <memgraph> λͺ…λ Ήμ–΄λ₯Ό ν†΅ν•΄μ„œ ν•΄λ‹Ή λ©”λͺ¨λ¦¬ κ·Έλž˜ν”„μ˜ 전체적인 μš”μ•½μ„ λ³Ό 수 μžˆλ‹€.

  • μ˜μ—­μ˜ λ©”λͺ¨λ¦¬ 크기, 더티 λ©”λͺ¨λ¦¬ 크기, μŠ€μ™‘λ˜κ±°λ‚˜ μ••μΆ•λœ λ©”λͺ¨λ¦¬μ˜ 양을 보여쀀닀.
  • dirty, swap μ˜μ—­μ΄ μ€‘μš” ..!
  • swap size λŠ” μ••μΆ•λœ 데이터 크기가 μ•„λ‹ˆλΌ 사전에 μ••μΆ•λœ 데이터 크기이닀.

vmmap <memgraph> λͺ…λ Ήμ–΄λ₯Ό μ΄μš©ν•˜λ©΄ 전체 μ˜μ—­μ— λŒ€ν•œ λ©”λͺ¨λ¦¬ 크기λ₯Ό 확인할 수 μžˆλ‹€.

  • Non-writable regions : ν”„λ‘œκ·Έλž¨μ˜ ν…μŠ€νŠΈ, μ‹€ν–‰ μ½”λ“œ λ“± μ“°κΈ°κ°€ λΆˆκ°€λŠ₯ν•œ μ˜μ—­

  • Writable regions : 데이터 μ„Ήμ…˜ λ“± μ“°κΈ° κ°€λŠ₯ν•œ μ˜μ—­, ν”„λ‘œμ„ΈμŠ€ νž™μ΄ 될 μœ„μΉ˜

  • vmmap κ³Ό awk λͺ…λ Ήμ–΄λ₯Ό ν†΅ν•΄μ„œ dirty page 개수λ₯Ό κ΅¬ν•˜λŠ” λͺ…령문을 μž‘μ„±ν•  수 μžˆλ‹€.

 

leaks

leaks λͺ…λ Ήμ–΄λ₯Ό 톡해 더이상 λ ˆνΌλŸ°μŠ€κ°€ μ—†μ§€λ§Œ ν• λ‹Ήλ˜μ–΄ μžˆλŠ” 객체λ₯Ό 확인할 수 μžˆλ‹€.

  • leak κ°μ²΄λŠ” μ ˆλŒ€ ν•΄μ œν•  수 μ—†λŠ” dirty memory μ΄λΌλŠ” 점을 κΈ°μ–΅..!

λ©”λͺ¨λ¦¬ λ””λ²„κ±°μ—μ„œ leak 을 ν™•μΈν•˜λŠ” 법

  • 3개의 객체가 κ°•ν•œ μ°Έμ‘°λ₯Ό ν•˜κ³  μžˆλŠ” μƒνƒœ

  • λˆ„μˆ˜λœ 객체λ₯Ό ν‘œμ‹œν•  뿐 μ•„λ‹ˆλΌ, retain cycle 도 ν‘œκΈ°λœλ‹€.
  • ν”„λ‘œμ„ΈμŠ€μ—μ„œ malloc μŠ€νƒ λ‘œκΉ…μ„ ν™œμ„±ν™”ν–ˆλ‹€λ©΄, 루트 λ…Έλ“œμ— λŒ€ν•œ 역좔적도 μ œκ³΅ν•œλ‹€.

heap

heap <memgraph> λͺ…λ Ήμ–΄λ₯Ό 톡해 νž™μ— ν• λ‹Ήλ˜μ–΄ μžˆλŠ” 객체듀을 λ³Ό 수 μžˆλ‹€.

  • λ©”λͺ¨λ¦¬μ— ν• λ‹Ήλœ 큰 κ°μ²΄λ‚˜, 같은 μ’…λ₯˜μ˜ 객체가 많이 μ‘΄μž¬ν•˜λŠ” 등을 μΆ”μ ν•˜λŠ”λ° 도움이 λœλ‹€.

λ©”λͺ¨λ¦¬ λ¦¬μ†ŒμŠ€ μ˜ˆμ™Έκ°€ λ‚¬μ„λ•Œμ˜ Memgraph λ₯Ό 가지고 확인해보면 각 객체의 클래슀 이름, 개체 수, 평균 크기 등이 μ œκ³΅λœλ‹€.

κΈ°λ³Έμ μœΌλ‘œλŠ” κ°œμˆ˜μ— 따라 μ •λ ¬λ˜κ³ , ν¬κΈ°μˆœλŒ€λ‘œ μ •λ ¬ν•˜κ³  μ‹Άλ‹€λ©΄ sortBySize μ˜΅μ…˜μ„ μΆ”κ°€ν•˜λ©΄ λœλ‹€.

  • 크기가 큰 NSConcreteData 객체 발견 πŸ‘€

NSConcreteData 객체쀑에 ν•˜λ‚˜μ˜ μ£Όμ†Œλ₯Ό 가져와야 ν•œλ‹€.

  • -addresses all μ˜΅μ…˜κ³Ό ν•¨κ»˜ 클래슀 이름을 μ „λ‹¬ν•˜λ©΄ 각 μΈμŠ€ν„΄μŠ€μ— λŒ€ν•œ νž™μ— μœ„μΉ˜ν•œ μ£Όμ†Œλ₯Ό 확인할 수 μžˆλ‹€.

malloc_history

malloc stack logging μ˜΅μ…˜μ„ ν™œμ„±ν™”ν•˜λ©΄ 각 할당에 λŒ€ν•œ backtrace λ₯Ό κΈ°λ‘ν•œλ‹€.

  • μ—­μΆ”μ λœ λ‘œκ·ΈλŠ” Memgraph λ₯Ό 기둝할 λ•Œ μΊ‘μ²˜λ˜μ–΄ μ‚¬μš©λœλ‹€.
  • malloc_history <memgraph> <address> λͺ…λ Ήμ–΄λ₯Ό ν†΅ν•΄μ„œ νŠΉμ • μ£Όμ†Œμ— μœ„μΉ˜ν•œ μΈμŠ€ν„΄μŠ€κ°€ ν• λ‹Ήλ˜λŠ” 것을 역좔적할 수 μžˆλ‹€.

NoirFilter.apply λ©”μ†Œλ“œμ—μ„œ μ—„μ²­ 큰 NS data λ₯Ό λ§Œλ“€κ³  μžˆλŠ” 것을 발견 πŸ§

πŸ™„ λ©”λͺ¨λ¦¬ λ¬Έμ œκ°€ λ°œμƒν–ˆμ„λ•Œ μ–΄λ–€ 도ꡬλ₯Ό μ„ νƒν•΄μ•Όν• κΉŒ?

μ•„λž˜ 세가지 μΌ€μ΄μŠ€μ— 따라 μ‚¬μš©ν•˜λŠ” 도ꡬ가 달라진닀.

  • 객체 생성을 보고 싢은지
    • malloc_history λͺ…λ Ήμ–΄λ₯Ό 톡해 λ©”λͺ¨λ¦¬ 할당을 역좔적 κ°€λŠ₯
  • λ©”λͺ¨λ¦¬μ˜ κ°μ²΄λ‚˜ μ£Όμ†Œλ₯Ό μ°Έμ‘°ν•˜λŠ” 것을 보고싢은지
    • leaks λͺ…λ Ήμ–΄λ₯Ό 톡해 λ©”λͺ¨λ¦¬ λˆ„μˆ˜ 확인 κ°€λŠ₯
  • μΈμŠ€ν„΄μŠ€κ°€ μ–Όλ§ˆλ‚˜ 큰지 ν™•μΈν•˜κ³  싢은지
    • vmmap, heap λͺ…λ Ήμ–΄λ₯Ό 톡해 크기 확인 κ°€λŠ₯

πŸ–Ό Images

iOS μ•±μ—μ„œ κ°€μž₯ 큰 κ°μ²΄λŠ” Images 이닀.

  • 이미지와 κ΄€λ ¨λœ λ©”λͺ¨λ¦¬ μ‚¬μš©μ€ 파일 크기가 μ•„λ‹Œ μ΄λ―Έμ§€μ˜ 크기와 관련이 μžˆλ‹€λŠ” 것이닀.
  • Memory use is related to the dimensions of the image, not the file size.
  • 파일 ν¬κΈ°λŠ” 590KB μ΄μ§€λ§Œ, μ΄λ―Έμ§€μ˜ ν¬κΈ°λŠ” 10MB 이닀.
    • 2048 * 1536 * 4bytes

🧐 μ™œ μ΄λ ‡κ²Œ μ‚¬μ΄μ¦ˆκ°€ 큰지 μ•ŒκΈ° μœ„ν•΄μ„œλŠ”.. iOS μ—μ„œ 이미지λ₯Ό μ²˜λ¦¬ν•˜λŠ” 방식을 μ•Œμ•„μ•Όν•œλ‹€

  • Load, Decode, Render 세가지 κ³Όμ •μœΌλ‘œ λ‚˜λ‰œλ‹€.
  • Load λ‹¨κ³„μ—μ„œλŠ” 590KB 의 μ••μΆ•λœ μ΄λ―Έμ§€νŒŒμΌμ„ λ©”λͺ¨λ¦¬μ— λ‘œλ“œν•œλ‹€.
  • Decode λ‹¨κ³„μ—μ„œ JPEG νŒŒμΌμ„ GPU κ°€ 읽을 수 μžˆλŠ” ν˜•μ‹μœΌλ‘œ λ³€ν™˜ν•œλ‹€. μ••μΆ•λœ 이미지λ₯Ό ν‘ΈλŠ” κ³Όμ •μ—μ„œ 10MB κ°€ λœλ‹€.
  • λ””μ½”λ”©λœ 후에 λ Œλ”λ§μ€ μ–Έμ œλ“  ν•  수 μžˆλ‹€.

SRGB

λ””μ½”λ”© 이후에 SRGB 포맷은 ν•œ ν”½μ…€ λ‹Ή 4 bytes λ₯Ό ν¬ν•¨ν•œλ‹€.

  • 일반적인 κ·Έλž˜ν”½μ˜ 이미지 포맷
  • Red, Green, Blue, Alpha

Wide format

iOS ν•˜λ“œμ›¨μ–΄λŠ” wide format 으둜 λ Œλ”λ§ ν•  수 μžˆλ‹€.

  • μ™€μ΄λ“œ 포맷은 SRGB 각각이 두배씩 λŠ˜μ–΄λ‚œ ν˜•νƒœλ‘œ, ν”½μ…€λ‹Ή 8 bytes λ₯Ό ν¬ν•¨ν•œλ‹€.
  • μ΄λ―Έμ§€μ˜ 크기λ₯Ό λ‘λ°°λ‘œ 늘리게 λœλ‹€.

  • μ’€ 더 μž‘μ€ ν˜•νƒœμ˜ 이미지 포맷,
  • ν•œ ν”½μ…€λ‹Ή 2 bytes λ₯Ό ν¬ν•¨ν•˜κ³ , νœ˜λ„μ™€ μ•ŒνŒŒ 값을 κ°–λŠ”λ‹€.

  • Alpha κ°’ ν•˜λ‚˜λ§Œ κ°–λŠ” 포맷으둜 1ν”½μ…€λ‹Ή 1 byte λ‘€ ν¬ν•¨ν•œλ‹€.
  • SRGB 에 λΉ„ν•΄ 75% 적은 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κΈ°μ— 흑백인 ν…μŠ€νŠΈλ‚˜ λ§ˆμŠ€ν¬μ— μ ν•©ν•˜λ‹€.

이미지 ν˜•μ‹μ€ 1ν”½μ…€λ‹Ή 1 byte μ—μ„œ 8 bytes κΉŒμ§€ λ‹€μ–‘ν•˜κΈ° λ•Œλ¬Έμ—, 상황에 따라 μ λ‹Ήν•œ 포맷을 선택해야 ν•œλ‹€.
μ–΄λ–»κ²Œ 선택해야 ν•˜λ‚˜.. μ‹Άμ—ˆμ§€λ§Œ, 포맷을 직접 μ„ νƒν•˜μ§€ μ•ŠμœΌλ©΄ λœλ‹€κ³  ν•œλ‹€ πŸ€“

  • UIGraphicsBeginImageContextWithOptions API λŠ” 항상 ν”½μ…€λ‹Ή 4 bytes λ₯Ό μ‚¬μš©ν–ˆμ§€λ§Œ,
  • UIGraphicsImageRenderer λ₯Ό μ‚¬μš©ν•˜λ©΄ μ μ ˆν•œ 포맷을 μ„€μ •ν•΄μ£ΌκΈ° λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆλ‹€.

UIGraphicsBeginImageContextWithOptions λ₯Ό 톡해 λ§ˆμŠ€ν¬μ— 원을 그리고 μžˆλ‹€

  • 검정색 원을 κ·Έλ¦¬λŠ”λ° ν”½μ…€λ‹Ή 4 bytes λ₯Ό μ‚¬μš©ν•˜λŠ” λΆˆν•„μš”ν•œ κ³Όμ •

UIGraphicsImageRenderer λ₯Ό μ‚¬μš©ν•˜λ©΄ 1ν”½μ…€λ‹Ή 1 byte λ₯Ό μ‚¬μš©ν•˜λ„λ‘ μžλ™μœΌλ‘œ λ³€ν™˜λœλ‹€.

  • ν•΄λ‹Ή 이미지λ₯Ό λ‹€μ‹œ μ‚¬μš©ν•΄μ„œ μƒ‰μƒλ§Œ λ³€κ²½ν•  μˆ˜λ„ μžˆλ‹€. 좔가적인 λ©”λͺ¨λ¦¬ 할당이 없이 색상을 λ³€κ²½ν•  수 μžˆλ‹€λŠ” 점!

⬇ Down sampling

일반적으둜 썸넀일을 λ§Œλ“€κΈ° μœ„ν•΄ 많이 μ‚¬μš©ν•˜λŠ” 이미지 λ‹€μš΄ μƒ˜ν”Œλ§

  • UIImage λ₯Ό μ‚¬μš©ν•΄μ„œ 사이징, 리사이징을 ν•˜λŠ”κ±΄ μ„±λŠ₯이 떨어진닀.
    • λ‚΄λΆ€ μ’Œν‘œ 곡간 λ³€ν™˜κ³Ό λ©”λͺ¨λ¦¬μ— μžˆλŠ” 전체 μ΄λ―Έμ§€μ˜ 압좕을 풀기에 μ„±λŠ₯이 떨어진닀.
  • ImageIO ν”„λ ˆμž„μ›Œν¬λ₯Ό μ‚¬μš©ν•˜λ©΄ 이미지λ₯Ό λ‹€μš΄μƒ˜ν”Œλ§ ν•  수 μžˆλŠ”λ°
    • κ²°κ³Ό μ΄λ―Έμ§€μ˜ dirty memory λΉ„μš©λ§Œ μ§€λΆˆ 수 μžˆλ„λ‘ 슀트리밍 API λ₯Ό μ‚¬μš©ν•œλ‹€.
    • λ©”λͺ¨λ¦¬ 슀파이크λ₯Ό 쀄일 수 μžˆλ‹€.

UIImage λ₯Ό μ‚¬μš©ν•΄μ„œ 더 μž‘μ€ μ΄λ―Έμ§€λ‘œ λ³€ν™˜ν•˜λŠ” μ½”λ“œ

ImageIO 둜 μ „ν™˜ν•œ μ½”λ“œ

  • λ””μŠ€ν¬μ—μ„œ νŒŒμΌμ„ λ‘œλ“œν•΄μ•Ό ν•˜λŠ”κ±΄ λ™μΌν•˜μ§€λ§Œ μ΄λ―Έμ§€μ˜ 크기λ₯Ό μ§€μ •ν•˜λŠ”κ±΄ λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 μ „λ‹¬ν•˜λ©΄ λœλ‹€.
  • λ³€ν™˜λœ CGImage λ₯Ό UIImage λ₯Ό λž˜ν•‘ν•  수 μžˆλ‹€.
  • 이미지 크기 λ˜ν•œ μž‘κ³ , 이전 μ½”λ“œλ³΄λ‹€ 50% λΉ λ₯΄λ‹€.

πŸ“± Optimizing when in the background

λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μ΅œμ ν™”ν•˜λŠ” 방법

  • μ•±μ˜ 전체 화면에 이미지가 μžˆλ‹€κ³  κ°€μ •ν•œλ‹€λ©΄, 앱이 μ•Œλ¦Όμ„ λ°›μ•„ λ‹€λ₯Έ ν™”λ©΄μœΌλ‘œ μ΄λ™ν•˜λ”λΌλ„ 계속 λ©”λͺ¨λ¦¬μ— λ‚¨μ•„μžˆκ²Œ λœλ‹€
  • ν‰μ†Œμ— 보지 λͺ»ν–ˆλ˜ 큰 λ¦¬μ†ŒμŠ€λŠ” μ–Έλ‘œλ“œ ν•˜λŠ” 것이 μ’‹λ‹€..
  • 앱이 λ°±κ·ΈλΌμš΄λ“œλ‘œ κ°€κ±°λ‚˜, ν¬κ·ΈλΌμš΄λ“œλ‘œ λŒμ•„μ˜€λŠ” 라이프 사이클 이벀트λ₯Ό μ΄μš©ν•˜μž.
  • λ°±κ·ΈλΌμš΄λ“œλ‘œ λ“€μ–΄κ°€λŠ” 경우 큰 이미지λ₯Ό μ–Έλ‘œλ“œ ν•˜κ³ , ν¬κ·ΈλΌμš΄λ“œλ‘œ λŒμ•„μ˜¬ λ•Œ 이미지λ₯Ό λ‹€μ‹œ λ‘œλ“œν•˜λ„λ‘ ν•œλ‹€.
  • λ°±κ·ΈλΌμš΄λ“œμ—μ„œ λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•˜κ³ , μ‚¬μš©μžκ°€ 앱을 μ‚¬μš©ν•˜λŸ¬ ν¬κ·ΈλΌμš΄λ“œλ‘œ 돌이올 λ•Œμ—λ„ λ™μΌν•˜κ²Œ μœ μ§€ν•  수 있게 λœλ‹€

navigation controller, tab controller 의 κ²½μš°μ—μ„œλ„ νŠΉμ • λ·° μ»¨νŠΈλ‘€λŸ¬κ°€ λ³΄μ΄κ±°λ‚˜ μ‚¬λΌμ§ˆ λ•Œ λ™μΌν•œ 처리λ₯Ό 해쀄 수 μžˆλ‹€.

 

728x90
728x90