Version: 2020.2
프로파일링
코루틴

메모리

메모리 소비는 성능을 나타내는 중요한 요소이며, 이는 특히 저사양 모바일 디바이스와 같이 제한된 메모리 자원을 가진 플랫폼에서 중요합니다.

메모리 소비 프로파일링

Unity에서 메모리 문제를 진단하는 가장 좋은 방법은 Unity의 Bitbucket에서 다운로드할 수 있는 오픈 소스 메모리 시각화 툴을 사용하는 것입니다. 이 툴을 사용하려면 간단히 연결된 저장소를 다운로드 받은 후, 포함된 Editor 폴더를 프로젝트로 이동시키면 됩니다.

이 툴은 Unity 버전 5.3 이후부터 지원되며, IL2CPP로 빌드된 애플리케이션에 추가된 경우, 네이티브 및 관리 코드의 메모리 소비에 대한 상당한 수준의 정보를 얻을 수 있습니다.

이 툴을 사용하려면 IL2CPP 스크립트로 작성된 프로젝트를 빌드한 이후, 이를 적절한 장치에 설치하면 됩니다. Unity의 에디터 내장 CPU 프로파일러를 연결한 후, 메모리 프로파일러 창을 열고(메뉴: Window > MemoryProfilerWindow), Take Snapshot 을 선택합니다.

장치의 애플레케이션은 잠시 정지되며, 데이터를 모으고 이를 Unity 에디터로 전송합니다. 그 이후, Unity 에디터는 잠시 정지한 후, 전송받은 데이터를 분석합니다. 이 과정은 상당한 시간이 걸릴 수 있습니다. 메모리를 많이 사용하는 애플리케이션의 경우, 트레이스 분석 과정은 약 10분에서 30분 정도 소요될 수 있습니다.

이 분석 및 로드 작업이 진행되는 동안 인내심을 가지고 기다리시기 바랍니다.

위의 스크린샷은 iOS 디바이스에서 작동하는 스탠다드 에셋 씬이며, 메모리 사용의 3/4 이상이 비행기의 동체에 관련된 네 개의 아주 거대한 텍스처에 할당된 것을 볼 수 있습니다.

이 시각화 그래프는 확대할 수 있습니다. 애플레케이션의 각 상자를 클릭하면 그에 대한 자세한 정보를 확인할 수 있습니다.

중복된 텍스처 식별

메모리에서 에셋이 중복되는 것은 자주 일어나는 메모리 문제 중 하나입니다. 보통 텍스처가 프로젝트에서 가장 메모리를 많이 차지하는 에셋이므로, 중복되는 것은 Unity 프로젝트에서 주로 발생하는 가장 일반적인 메모리 문제 중의 하나입니다.

중복된 에셋을 파악하려면, 동일한 에셋에서 로드된 동일한 종류와 크기를 가지는 두 개의 오브젝트를 찾아보면 됩니다. 새로운 메모리 프로파일러의 세부 정보 창에서 동일한 것으로 보이는 오브젝트의 NameInstanceID 필드를 확인해 보십시오.

Name 필드는 오브젝트가 로드된 에셋 파일의 이름에 따릅니다. 일반적으로, 필드의 값은 파일의 경로와 확장자가 빠진 파일 이름입니다. InstanceID 필드는 Unity 런타임이 할당한 내부 식별 번호이며, 이 숫자는 Unity 게임의 단일 실행 동안 고유합니다(1).

위의 다이어그램은 이 문제의 간단한 예제를 보여줍니다. 다이어그램 왼쪽과 오른쪽에는 메모리 프로파일러 5.4 버전의 세부 정보 창의 스크린샷이 있습니다. 스크린샷에서 보이는 에셋은 메모리에 각각 따로 로드된 두 개의 텍스처입니다. 이 텍스처는 동일한 이름과 용량을 가지고 있으므로, 중복일 수 있습니다. 프로젝트의 “Assets” 폴더를 살펴보면, 그 안에 wood-floorboards-texture 라는 이름을 가진 에셋 파일이 오직 한 개라는 사실을 알 수 있으며, 이는 에셋 중복을 강하게 나타냅니다.

메모리에 있는 각각의 UnityEngine.Object는 고유한 인스턴스 ID가 있으며, 이는 오브젝트가 생성되는 시점에서 할당된 것들입니다. 이들 텍스처는 서로 다른 인스턴스 ID가 있다는 것을 고려했을때, 현재 메모리에는 서로 다른 두 개의 텍스처 데이터 집합이 로드되고 있다는 것을 알 수 있습니다.

파일 이름과 에셋 크기가 동일하며, 인스턴스 ID가 다르므로, 이들 두 오브젝트는 메모리에서 중복된 텍스처를 나타내고 있음을 확실하게 알 수 있습니다(참고: 만일 프로젝트에 동일한 파일 이름을 가지는 텍스처가 있는 경우, 이 판단이 절대적이지는 않지만, 동일한 파일 크기인 경우에는 중복되었다고 판단해도 무방합니다.)

에셋 번들(AssetBundles) 또는 에셋(Asset) 중복

메모리에 텍스처나 에셋이 중복되는 가장 주된 이유는, 에셋 번들을 부적절하게 언로드하기 때문입니다. 이 문제에 대한 자세한 내용은 Unity의 에셋 번들 베스트 프랙티스를 참조하십시오. 핵심 섹션은 로드된 에셋 관리 입니다.

이미지 버퍼, 이미지 이펙트, RenderTexture 메모리 사용 점검

메모리 비주얼라이저 툴에서 이미지 이펙트나 RenderTexture 오브젝트에 렌더 버퍼를 제공하기 위해 요구되는 메모리를 시각화하는 것 역시 가능합니다.

위의 스크린샷은 몇몇 Unity의 시네마틱 이미지 이펙트가 적용된 간단한 씬을 보여주고 있습니다. 이미지 이펙트는 연산을 수행하기 위해서 임시로 렌더 버퍼를 할당합니다. 특히, 블룸 효과는 점점 크기가 작아지는 몇몇 버퍼를 할당합니다. 레티나 iOS 기기는 고해상도 장치이므로, 이러한 임시 버퍼는 프로젝트의 다른 부분보다 상당히 더 많은 양의 메모리를 소모합니다.

iPad Air 2의 경우, 이 태블릿 장치는 2,048x1,536 해상도로 그리게 되는데, 이는 최신 콘솔이나 PC가 목표로 하는 1,080p 해상도 이상입니다. 전체 화면의 임시 렌더 버퍼는 24 또는 36MB의 메모리를 버퍼 포맷에 따라서 소모합니다. 이 값은 렌더 버퍼의 픽셀 치수를 절반으로 줄이는 것으로 그 크기를 75% 감소시킬 수 있습니다. 이렇게 하더라도, 렌더 결과물의 시각적 품질은 그다지 나빠지지는 않습니다.

이미지 이펙트의 임시 렌더 버퍼나 다른 GPU 자원의 사용을 최적화하는 한 방법으로는, 이렇게 서로 분리된 산출 과정을 동시에 수행하는 단일 “uber” 이미지효과를 생성합니다. Unity 버전 5.5 이상을 사용하는 경우, 새로운 UberFX (github에서 다운로드 가능)패키지를 사용할 수도 있습니다. 이 패키지는 시네마틱 이미지 이펙트가 제공하는 모든 기능을 수행할 수 있고 개별 이미지 이펙트보다 오버헤드가 적으며 설정 가능한 “uber” 이미지 이펙트를 제공합니다.

프로파일링
코루틴