[iOS] imageIO_PNG_Data가 메모리에 상주하고 있는 이유
iOS 12버젼이 나오면서 메모리가 늘어났다는 얘기가 나와서 프로파일링을 해보았다. 여기서는 메모리가 OS업그레이드에 따라 올랐다는 내용을 다루려는 것은 아니고, 프로파일링하는 도중에 만난 imageIO_PNG_Data에 대한 이야기이다.
사용 중인 Unity버젼은 2017.4.3f1이고, 이후 버젼에 대해서는 테스트해보지 않았다. 아래의 그림은 XCode의 instrument (Allocation) 툴을 실행하여 메모리가 얼마나 사용중인지 확인중인 화면이다. (XCode의 메뉴에서 Open Developer Tool > Instrument로 실행할 수 있다.)
위 그림에서 레퍼런스 카운트가 1이고, 10.47MB나 차지하고 있는 ImageIO_PNG_Data을 볼 수 있다. 저 ImageIO_PNG_Data는 게임을 런칭하고 종료할 때까지 계속 상주하며 10.47MB나 차지하고 있다. 구글링을 해보면 stack overflow에서 관련 질답을 볼수 있다. https://stackoverflow.com/questions/31952201/ios-instruments-shows-imageio-png-data-is-300x-larger-in-size-than-its-actual-i
[UIImage imageNamed:@”Submit.png”];
[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@”/Submit.png”]];
대략 답변은 imageNamed API를 쓰지말고, imageWithContentsOfFile API로 사용하라는 것이었다. imageNamed에 대해서 알아볼 필요가 있었다. Apple의 메뉴얼을 찾아보았다.
Use the imageNamed:inBundle:compatibleWithTraitCollection: method (or the imageNamed: method) to create an image from an image asset or image file located in your app’s main bundle (or some other known bundle). Because these methods cache the image data automatically, they are especially recommended for images that you use frequently.
https://developer.apple.com/documentation/uikit/uiimage?language=objc
간단히 해석해보면, 이 메서드는 이미지 데이터를 자동으로 캐쉬하기 때문에, 자주 사용하는 이미지를 대상으로 사용되도록 추천한다라는 것이다. 캐쉬된 데이터이기 때문에 메모리에서 해제되지 않고 머무르고 있는 것이라는 얘긴데, 저건 언제 쓰이는 것인지 궁금했다. XCode에서 코드 검색을 해보니 플랫폼연동한 어떤 라이브러리와 SplashScreen.mm파일에서 imageNamed이 사용되고 있는 것을 찾을 수 있었다.
이 SplashScreen.mm은 Unity에서 iOS빌드시 Generate되는 파일이고, imageNamed는 Launch 이미지용(즉, 화면 해상도에 따라 풀스크린 세팅용)으로 사용중이었다. 어짜피 최초 실행시에만 사용되는 것이어서 imageNamed를 사용할 필요는 없어보이지만 또 다른 이유나 사정이 있을 수 있으니, Unity 측에 기회가 되면 건의를 해볼 필요는 있을 것 같다. 메모리를 아껴써야 하는 저사양폰에서는 10MB 절약하는 것이 큰 도움이 될 수도 있기 때문에 사소한 이슈만은 아닌 것으로 생각된다.
이 코드 부분을 제외하고 빌드하여 테스트해보니 imageIO_PNG_Data가 메모리에서 해제되어 더이상 노출이 되지 않았다.