게임을 개발함에 있어서 가장 중요한 것은 물론 재미입니다. 게임은 재미를 주는 것이 주 목적이니 당연한 이야기겠죠. 하지만, 게임을 아무리 재밌게 만들었다 하더라도 게임이 실행이 되야 재미를 느낄 수 있겠죠. 게임을 플레이하다가 게임이 자꾸 강제 종료되버린다면 말짱 도루묵이 되겠죠.

그렇기 때문에 게임 개발에 있어서 메모리 이슈도 중요합니다. 특히 모바일 환경에서는 더 심하죠. PC에서는 실제 물리적인 램이 부족하더라도, 디스크의 공간을 활용하여 모자란 메모리를 보조하는 시스템이 존재합니다. 때문에, 현대의 PC에서는 게임이 버벅일지언정 메모리 부족으로 게임이 강제종료되는 상황까지 가는 것이 흔치는 않습니다. 하지만, 스마트폰에는 그러한 기능이 존재하지 않습니다. 그말인 즉슨, 실제의 물리적인 메모리 공간을 넘어서 사용이 불가능하다는 것을 의미합니다. 그렇기때문에, 스마트폰 게임이 메모리를 많이 사용한다는 것은 게임이 뜻하지 않게 강제종료될 가능성이 그만큼 많아진다는 것을 의미합니다.  

스마트폰 게임을 개발할 때에는 항상 메모리에대해서 신경쓰면서 개발을 해야합니다. 하지만 메모리를 줄여야 하는 것은 알겠는데, 무엇을 어떻게 줄여야 할지 막막한 채로 작업을 할 수는 없겠죠. 그렇기 때문에  메모리도 프로파일링이 필요합니다.


유니티 5.3부터는 메모리 프로파일러라는 확장 툴을 이용하여 메모리를 확인할 수 있습니다. 이 툴을 이용하면 어떤 메모리가 얼만큼의 힙 메모리를 사용하고 있는 지를 직관적으로 쉽게 확인 할 수 있습니다.

다운로드 : https://bitbucket.org/Unity-Technologies/memoryprofiler/downloads/

아쉽게도 아직 유니티 기본 내장 툴은 아니고, 에디터 확장 기능으로 따로 다운로드받아서 사용해야합니다. 유니티도 오픈소스 형태로 개발하는 기능들이 많이 있는데요, 빗버킷에 올려두고 개발을 진행합니다. GUI 시스템도 마찬가지고 Post Processing Stack, Asset Bundle Manager 등등 많은 프로젝트들이 오픈소스 형태로 진행중입니다. 메모리 프로파일러 역시 이 중 하나라고 보시면 됩니다. 

유니티 5.3 이상부터 적용이 가능합니다. 다운로드 받은 프로젝트의 에디터 폴더를 현재 현재 개발중인 프로젝트의 에디터 폴더로 임포트 하면 됩니다. 스크립트 백엔드는 IL2CPP로 적용해줘야합니다. 안드로이드 역시 IL2CPP가 정식 지원되고 있기 때문에 안드로이드도 사용이 가능합니다. 다만 주의할 점은 5.3에서는 안드로이드 IL2CPP가 정식 지원이 아니라는 점입니다. 결론적으로는 메모리 프로파일러를 이용하려면 5.3을 이용중인 프로젝트라면 5.4 이상으로 업데이트를 해야한다는 의미가 됩니다.

메모리 프로파일러는 내부적으로 Profiler API를 이용합니다. 그렇기 때문에, Development Build로 빌드하여야 합니다. 게임을 띄우고나면 유니티 프로파일러를 띄우고 디바이스에 프로파일러를 연결하여 프로파일링이 되는 것을 확인합니다, 그 뒤에 유니티에서 Windows>Memory Profiler를 선택합니다.

그럼 이렇게 생긴 메모리프로파일러 윈도우가 뜹니다. 이 화면에서 Take Snapshot 버튼을 누르면 됩니다. 디바이스에서 데이터 긁어오다보니까 폰이 잠깐 멈췄다가 가져온 데이터를 분석하느라 에디터가 잠깐 멈출겁니다. 데이터가 많으면 좀 시간이 걸릴 수도 있기 때문에 인내심이 좀 필요할수도 있습니다.

데이터 분석이 다 끝나면 메모리 사용량을 종류별로 시각화 보여줍니다. 종류별로 메모리를 얼마만큼 차지하는지를 사각형의 크기로 보여줍니다. 사각형 크기 비율이 실제의 메모리 사용량의 비율을 나타냅니다. 즉, 사각형의 크기가 큰 것 을 우선순위로 줄여나가면 되는 것입니다.

항목을 클릭하면 개별 리소스나 오브젝트들의 메모리 차지 면적을 볼 수 있습니다. 우측에는 선택한 오브젝트의 이름 및 인스턴스 아이디 등등의 자세한 내용을 확인할 수 있습니다. 크기가 작아서 보기 힘든 항목들은 마우스 휠을 굴려서 줌인 줌아웃이 가능합니다. 솔직히 인터페이스가 이쁜 편은 아닙니다. 좀 투박한 느낌은 있지만 시각적으로 확인하고 분석하는 기능은 충분합니다.


실제의 예를 하나 들어보겠습니다. 에셋스토어에서 게임을 하나 받아서 갤럭시S2에서 수행한 모습입니다. 2D게임이라 갤럭시 2S에서도 동작하는데 무리가 없습니다.

근데, 문제가 없어보인 것이지 실제로는 문제가 있는 상황입니다. 프로파일링해보기 전에는 문제가 없다고 단정하면 안됩니다. 실제로 메모리 프로파일러로 확인해보니 텍스쳐 메모리 사용량이 엄청납니다. 어떤 텍스쳐는 16MB나 차지하고 있습니다. 

확인해보니 사이즈가 2048이기는 하지만 ETC2 압축을 설정해놓았으니 16MB는 말이 안되는 것 같아보입니다.

사실, 이건 갤럭시2S가 OpenGL ES 2.0만 지원해서 발생하는 현상입니다. 갤럭시 S2는 오래된 모델이라 OpenGL ES 3.0을 지원하지 못하고 OpenGL ES 2.0만 지원합니다. 문제는 ETC2는 OpenGL ES 3.0부터 지원된다는 것입니다. 즉 OpenGL ES2.0에서는 ETC2를 사용하지 못한다는 것입니다. 그래서 OpenGL ES 2.0에서는 ETC2 텍스쳐를 읽어들일 때 ETC2를 압축을 풀어서 메모리에 올라갑니다. 그래서 2048 * 2048 * 4바이트 = 16MB가 되서 메모리에 올라간 것입니다. 

똑같은 텍스쳐를 OpenGL ES 3.0 지원되는 기기에서 확인해보면  텍스쳐 압축이 잘 되서 4MB로 올라갑니다. 그래서 알파가 있는 텍스쳐를 컴프레스트로 두면 OpenGL ES 2.0까지만 지원하는 갤럭시S2랑 OpenGL ES 3.0을 지원하는 갤럭시 S4에서의 실제 텍스쳐 메모리 사용량이 많이 차이가 날 겁니다. (갤럭시 S3로 비교하지 않은 이유는, 갤럭시 S3 중에서도 세부 기종에따라 지원하는 버전이 다르기 때문입니다)


메모리 프로파일러를 이용하면 이런식으로 어떤 리소스가 얼만큼을 차지하고 있는 지를 쉽게 분석할 수 있습니다. 메모리를 프로파일링하기 위해서는 필수적인 툴일 것입니다.

이 툴에 대하여 건의 사항이나 버그가 있다면 아래 주소로 이슈를 만들어주시면 됩니다. 만약 영어가 불편하면 저한테 말씀해주세요.

링크 : https://bitbucket.org/Unity-Technologies/memoryprofiler/issues?status=new&status=open

 제가 사실 블로그 댓글은 잘 확인하지를 않아서 페이스북이나 트위터로 연락 주세요 :)

페이스북 : ozlael.oz

트위터 : @ozlael

신고

+ Recent posts