일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- ios
- Xcode
- combine
- RxCocoa
- SWIFT
- UICollectionView
- 스위프트
- Protocol
- 클린 코드
- Refactoring
- swift documentation
- ribs
- MVVM
- 리펙토링
- tableView
- Human interface guide
- uitableview
- Observable
- HIG
- UITextView
- clean architecture
- swiftUI
- Clean Code
- rxswift
- uiscrollview
- 애니메이션
- map
- collectionview
- 리팩토링
- 리펙터링
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 3. Memory Deep Dive - Memory Footprint (페이징, Compressed 메모리, NSCache vs Dictionary) 본문
[iOS - swift] 3. Memory Deep Dive - Memory Footprint (페이징, Compressed 메모리, NSCache vs Dictionary)
jake-kim 2023. 12. 10. 01:04
1. Memory Deep Dive - iOS 메모리 운영체제 기초 (가상 메모리, 페이징, clean memory, dirty memory, compressed memory)
2. Memory Deep Dive - Memory를 줄여야 하는 이유 (+ 앱 메모리 사용량 아는 방법)
3. Memory Deep Dive - Memory Footprint (페이징, Compressed 메모리, NSCache vs Dictionary)
4. Memory Deep Dive - Memory Footprint 프로파일링 방법 (Allocation, Leaks, VM Tracker, Virtual memory trace)
5. Memory Deep Dive - Memory Footprint 프로파일링 방법 (2) (Xcode Memory Debugger, Memory Graph, Memgraph)
6. Memory Deep Dive - Memory Footprint 프로파일링 방법 (3) (vmmap, leaks, heap, malloc_history)
7. Memory Deep Dive - 이미지 로드 매커니즘, 이미지 핸들링 최적화 (UIGraphicsBeginImageContextWithOptions, UIGraphicsImageRenderer)
8. Memory Deep Dive - 이미지 리사이징, 이미지 다운 샘플링 (ImageIO, ImageSource)
9. Memory Deep Dive - 백그라운드에서 메모리 최적화하는 방법
메모리 관리
- 전 포스팅 글에서 알아보았듯이, 메모리는 페이징 이라는 것을 사용하여 관리
- 힙 메모리 안에서 page하나당 여러개의 UIView, String과 같은 인스턴스를 관리하거나 여러 페이지에 Data가 걸쳐있는 경우가 존재
- 일반적으로 page 하나당 크기는 16K이며, clean되거나 dirty 될 수 있음
- clean: 데이터가 아직 사용되지 않음
- dirty: 데이터가 사용됨
- 앱의 메모리 사용량 = page 수 * 페이지 크기 (16K)
- ex) Int 배열을 힙에 할당했을때 동작
- 메모리 사용 관점 - 만약 위 데이터를 6개의 페이지를 통해 관리할 경우?
- 20000개의 정수 배열 할당 -> 힙 영역에 clean memory 상태로 저장
- 0번째 인덱스에는 32, 19999인덱스에는 64를 할당 -> 데이터 버퍼에 write하기 시작하면 0번째 인덱스와 19999번째 인덱스를 갖고 있는 page는 dirty상태로 변함
- (즉 0과 19999인덱스에 영향을 받아서 1페이지와 6페이지 영역이 dirty 상태로 변함)
또 다른 예) jpg 파일을 메모리에 저장하는 경우
- 50KB .jpg파일을 저장할 때, 한 페이지 당 16KB이기 때문에 4페이지가 필요
- 이때 마지막 4번째 페이지는 공간이 남아있으므로 다른 데이터 저장이 가능 (단, 해당 페이지가 clean 상태여야 사용이 가능)
메모리가 dirty, clean 상태에 따라 알 수 있는 것
- 프로퍼티를 사용할 때 setter로 선언하지 않고 getter로만 선언하면 page가 항상 clean 상태로 유지됨
앱 메모리 Clean 개념
- page out될 수 있는 메모리
- * page out: 가상메모리에서 프로세스가 필요로 하는 데이터를 물리적인 메모리에 올리고(unload) 필요 없는 데이터는 디스크에 내보냄(page out)으로써 메모리를 효율적으로 사용하는데 여기서의 page out을 의미
- 프레임워크도 페이징이 될 수 있음
- clean 상태가 되면 스위즐링도 가능
앱 메모리 Dirty 개념
- 할당된 메모리
- 프레임워크도 dirty상태가 될 수 있음
앱 메모리 Compressed 개념
- iOS 7부터 도입
- 사용되지 않은 메모리를 가져와서 압축하여 더욱 많은 메모리를 사용하게끔 만드는 원리
- 액세스할 시점에는 다시 압축을 풀어서 접근함
ex) 캐싱을 위해 Dictionary가 있을때, 여기에 총 5페이지 중 2페이지만 사용하는 경우
- 3페이지는 액세스하지 않았기 때문에 3페이지를 하나의 페이지로 압축함
Memory Warnings과 Compressed Memory
- Compressed memory는 이전보다 더 많은 메모리를 사용할 수 있기 때문에 메모리 해제를 복잡하게 만듦
- 때문에 메모리 경고가 발생할 때 잠시 아무것도 캐싱하지 않거나, 일부 백그라운드 작업을 제한하는 작업이 권장
didReceiveMemoryWarning() 핸들링
- 앱 메모리 경고 메서드가 있지만, 보통 핸들링하지 않는 경우가 있는데 실제로는 여기서 메모리 관련 처리가 필요함
// AppDelegate.swift
func applicationDidReceiveMemoryWarning(_ application: UIApplication) {
}
- iOS7부터 Compressed Memory를 사용하여, 이전보다 더 많은 메모리를 사용할 수 있고 메모리 해제가 복잡한데 이 영향에 의하여 메모리 경고 처리가 필요함
- 캐싱을 제거하는 방법이 가장 쉽고 간편한 방법
Dictinoary가 아닌 NSCache로 캐싱해야 하는 이유
- didReciveMemorywarning()을 다루기 전에 먼저, 캐싱을 할때 NSCache와 Dictinoary를 사용할 수 있는데 NSCache를 사용하는 것이 thread-safe하므로 NSCache가 안전함
- NSCache가 메모리를 할당하는 방식에 있어서 더욱 purgeable 함 (=더욱 메모리 제거가 쉬움)
- 메모리가 부족하다는 델리게이트 메서드가 있는데 여기에서 메모리를 관리하는 방법?
- NSCache를 사용하고 있다면, didReceiveMemoryWarning에서 cache의 데이터들을 removeAllObjects()하여 핸들링이 필요
* 참고