필자는 아직 국내에 출시되지 않은 아이패드 3세대를 미국 현지 친척에게 부탁하여 어렵게 전달받았습니다.
아이패드3 출시 이전 레티나 채용에 대해 필자는 매우 부정적이었습니다.
고해상도 2048x1536을 위한 이미지로딩과 처리를 위해서는 매인메모리가 최소한 2기가는 되어야 한다는게 필자의 생각이었고
메모리를 2기가로 탑재한다고 해도 2기가의 메모리에 전력공급을 위한 배터리 성능 문제와 발열 문제등을 예상하여
아이패드3에는 레티나가 지원되지 않을 것이며, 만일 나온다면 매인메모리는 반드시 2기가 이상이어야 한다는게 필자의 주장이었습니다.
순전히 개발자 입장에서의 주장이었죠.
그러나 막상 아이패드 3세대는 물리적 해상도 2048x1536으로 나왔고 메모리는 아이패드2의 2배인 1기가로 알려졌습니다.
필자는 궁금했습니다.
과연 1기가의 메모리로 고해상도 이미지 처리와 운용이 멀티태스킹(스위칭)과 함께 아이패드2 보다 쾌적한 환경을 제공할까?
만일 그렇다먄 애플은 기술적으로 어떻게 해결했을까?
gpu에 자체 이미지 디코딩 기능을 넣었을까?
획기적인 메모리 스왑 기술이 들어 갔을까?
결론은...
아이패드3의 레티나 채용으로 인해 예상되는 메모리 부족(?)현상에 애플은 기술적으로 그 어떤 해결책도 넣지 않았습니다.
지금부터 제가 나름대로 실험한 내용을 소개하고자 합니다.
무척이나 제한적인 실험이라 100% 정확하지 않을 수도 있음을 먼저 말씀드립니다.
1. 사전 인지 사항
아이패드1은 물리해상도 1024x768로서 매인메모리는 256MB입니다.
아이패드2는 물리해상도 1024x768로서 매인메모리는 512MB입니다.
아이패드3는 물리해상도 2048x1536으로 매인메모리는 1GB입니다.
1픽셀의 표시를 위해서는 RGBA(Red/Green/Blue/Alpha)값 각 1바이트씩 4바이트의 메모리가 요구됩니다.
2. 실험의 목적
본 실험은 이미지가 메모리에 어떻게 로드되고 관리되는지 알아보기 위한 목적입니다.
그리고 이미지 로딩을 계속하여 언제 메모리 부족이 발생하여 앱이 강제종료 되는지 알아보기 위한 실험입니다.
실제 개발에서는 출력될 이미지 크기에 맞게 리사이징 하거나 임시저장과 복원을 통한 스와핑등 코드 최적화를 통해 메모리 관리를 하지 이렇게 코딩하는 개발자는 아무도 없을 것입니다. ^^
3. 준비 사항
먼저 아래의 그림처럼 하나의 뷰컨트롤러 기반의 간단한 앱 프로젝트를 생성하여 이미지 로드 버튼을 올리고 이미지가 몇 번 로드 되었는지 나타내는 레이블을 하나 만들었습니다. 버튼을 클릭하면 이미지를 로드하는데 1024x768의 test.png 파일과 2048x1536 test@2x.png 파일 리소스가 로딩되도록 하였습니다.
"Load Image" 버튼을 클릭하면 아래의 코드가 실행되도록 하였습니다.
NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"png"];
UIImage *windowImage = [[[UIImage alloc] initWithContentsOfFile:path] autorelease];
[capturedImages addObject:windowImage];
captureCount.text = [NSString stringWithFormat:@"%d times loaded.", [capturedImages count]];
UIImageView *iv = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)] autorelease];
iv.contentMode = UIViewContentModeScaleAspectFill;
iv.image = windowImage;
[self.view addSubview:iv];
여기서 imageNamed 메서드 대신 initWithContentsOfFile을 사용한 이유는 imageNamed로 동일한 이미지 리소스를 로딩할 경우 새로운 메모리를 생성하지 않고 처음에 로딩된 기존 메모리영역을 그대로 이용하기 때문입니다.
그리고 앱의 메모리 현황을 보기 위해 Instruments를 이용하였습니다.
파란색으로 선택된 앱이 실험으로 사용된 앱이며 Real Mem 항목이 해당 앱이 사용하고 있는 메모리량을 표시하는 곳입니다.
4. 아이패드1 에서의 실험
아이패드1에서는 1024x768 크기의 test.png 이미지가 로드됩니다.
아래의 그림은 이미지가 하나씩 로드될 때 마다 메모리량을 나타낸 것입니다.
위의 그림에서 알 수 있듯이 실험 앱의 메모리 용량이 4메가 -> 7메가-> 10메가 각 3메가씩 늘어남을 알 수 있습니다.
이는 한 이미지의 RAW 데이터 용량인 1024x768x4 = 3메가 라는 용량과 거의 일치합니다.
이렇게 이미지를 하나씩 로드를 하니 40번째 이미지가 로드될 때 메모리 부족으로 앱이 강제 종료되었습니다.
3메가 x 40 = 120메가 정도로서 iOS 5.1과 필수 기본 앱들이 차지하고 있는 용량등을 합산하면
알려진대로 여유메모리의 2~30%정도가 남겨진 상태에서 앱이 강제종료 되는 것입니다.
5. 아이패드3에서의 실험
아이패드3에서는 2048x1536 크기의 test@2x.png 레티나 이미지가 자동으로 로드됩니다.
아래의 그림은 이미지가 하나씩 로드될 때 마다 메모리량을 표시를 나타낸 것입니다.
위의 그림에서 알 수 있듯이 아이패드3 실험 앱의 메모리 용량이 4메가 -> 16메가-> 28메가 각 12메가씩 늘어남을 알 수 있습니다.
이는 한 이미지의 RAW 데이터 용량인 2048x1536x4 = 12메가 라는 용량과 거의 일치합니다.
이렇게 이미지를 하나씩 로드를 하니 48번째 이미지가 로드될 때 메모리 부족으로 앱이 강제 종료되었습니다.
12메가 x 48 = 576메가 정도로서 iOS 5.1과 필수 기본 앱들이 차지하고 있는 용량을 합산하면
알려진대로 여유메모리의 2~30%정도가 남겨진 상태에서 앱이 강제종료 되는 것입니다.
'iOS Programming' 카테고리의 다른 글
NSLog를 확장하여 사용하기 - 로그로 가득찬 로그콘솔을 보다 보기 쉽게 구현하자. (0) | 2012.08.28 |
---|---|
XML 데이터를 NSArray와 NSDictionary로 구조화하자. (1) | 2012.08.27 |
Xcode 4.2 도움말 설정하기 (1) | 2011.10.07 |
xcode4 초간단 살펴보기 (0) | 2011.03.10 |
구글 챠트를 이용해 iOS에서 챠트 쉽게 구현하기 (0) | 2011.01.05 |