에셋 번들 메모리 오버헤드
에셋 번들을 로드하면 Unity는 번들의 내부 데이터를 저장하기 위한 메모리와 번들에 포함된 에셋을 위한 메모리를 할당합니다. 로드된 에셋 번들에 대한 내부 데이터의 주요 유형은 다음과 같습니다.
- 로딩 캐시: AssetBundle 파일에서 최근 액세스된 페이지를 저장합니다. 크기를 제어하려면
AssetBundle.memoryBudgetKB
를 사용하십시오. - TypeTree: 오브젝트의 직렬화된 레이아웃을 정의합니다.
- 목차: 에셋을 번들에 나열합니다.
- 사전 로드 표: 각 에셋의 종속성을 나열합니다.
어드레서블 그룹과 에셋 번들을 구성할 때는 생성 및 로드하는 에셋 번들의 크기와 수 사이에서 적절한 균형을 찾아야 합니다. 더 적은 수의 큰 번들을 사용하면 에셋 번들의 총 메모리 사용량을 최소화할 수 있습니다. 하지만 작은 번들을 많이 사용하면 Unity가 에셋과 에셋 번들을 쉽게 언로드할 수 있으므로 최대 메모리 사용량을 최소화할 수 있습니다.
디스크에 저장된 에셋 번들의 크기는 런타임 시 에셋 번들의 크기와 동일하지 않습니다. 하지만 빌드에서 에셋 번들의 메모리 오버헤드에 대한 가이드로 디스크 크기를 사용할 수 있습니다. 에셋 번들 분석에 도움이 되는 번들 크기 및 기타 정보는 빌드 레이아웃 보고서에서 찾을 수 있습니다.
TypeTree
TypeTree는 프로젝트 내 데이터 유형의 필드 레이아웃을 설명합니다.
에셋 번들에서 직렬화된 각 파일에는 파일 내 각 오브젝트 유형에 대한 TypeTree가 있습니다. TypeTree 정보를 사용하면 직렬화된 방식과 약간 다르게 역직렬화된 오브젝트를 로드할 수 있습니다. TypeTree 정보는 에셋 번들 간에 공유되지 않으며, 각 번들에는 포함된 오브젝트에 대한 전체 TypeTree 세트가 있습니다.
Unity는 에셋 번들을 로드할 때 모든 TypeTree를 로드하며, 에셋 번들의 수명 기간 동안 메모리에 보관합니다. TypeTree와 관련된 메모리 오버헤드는 직렬화된 파일에 있는 고유한 유형의 수와 해당 유형의 복잡도에 비례합니다.
TypeTree 메모리 줄이기
다음과 같은 방법으로 에셋 번들 TypeTree의 메모리 요구 사항을 줄일 수 있습니다.
- 동일한 유형의 에셋을 동일한 번들에 함께 보관합니다.
- TypeTree를 비활성화하고 번들에서 TypeTree 정보를 제외하여 에셋 번들을 더 작게 만듭니다. 그러나 TypeTree 정보가 없으면 이전 버전의 번들을 최신 버전의 Unity로 로드하거나 프로젝트에서 스크립트를 변경할 때 직렬화 오류 또는 정의되지 않은 동작이 발생할 수 있습니다.
- 간단한 데이터 유형을 사용하면 TypeTree 복잡성을 줄일 수 있습니다.
TypeTree가 에셋 번들의 크기에 미치는 영향을 테스트하려면 비활성화된 TypeTree가 있는 상태와 없는 상태로 빌드하여 크기를 비교합니다. BuildAssetBundleOptions.DisableWriteTypeTree
를 사용하여 에셋 번들에서 TypeTree를 비활성화할 수 있습니다.
[!참고] 일부 플랫폼에서는 TypeTree를 필요로 하며
DisableWriteTypeTree
설정을 무시합니다. 또한 TypeTree를 지원하지 않는 플랫폼도 있습니다.
프로젝트에서 TypeTree를 비활성화하는 경우 새 플레이어를 빌드하기 전에 항상 로컬 어드레서블 그룹을 다시 빌드하십시오. 프로젝트에서 콘텐츠를 원격으로 배포하는 경우 플레이어를 생성할 때 사용한 것과 동일한 버전(패치 번호 포함)의 Unity를 사용하고 사소한 코드 변경은 적용하지 마십시오. 여러 Unity 버전, 업데이트, 플레이어 버전을 사용하면 TypeTree 비활성화를 통한 메모리 절약의 가치를 충분히 활용하기 어려울 수 있습니다.
목차
목차는 명시적으로 포함된 각 에셋을 이름별로 조회하는 데 사용할 수 있는 번들 내의 맵입니다. 에셋의 수와 매핑되는 문자열 이름의 길이에 따라 선형적으로 확장됩니다.
목차 데이터의 크기는 총 에셋 수를 기준으로 합니다. 목차 데이터를 저장하는 데 사용되는 메모리 양을 최소화하려면 특정 시간에 로드되는 에셋 번들의 수를 최소화해야 합니다.
사전 로드 표
사전 로드 표는 에셋이 참조하는 다른 모든 오브젝트의 목록입니다. Unity는 에셋 번들에서 에셋을 로드할 때 사전 로드 표를 사용하여 이렇게 참조되는 오브젝트를 로드합니다.
예를 들어 프리팹에는 각 컴포넌트와 머티리얼 또는 텍스처와 같이 참조할 수 있는 다른 에셋에 대한 사전 로드 엔트리가 있습니다. 각 사전 로드 엔트리는 64비트이며 다른 에셋 번들의 오브젝트를 참조할 수 있습니다.
한 에셋이 다른 에셋을 참조하고 그 에셋이 또 다른 에셋을 참조하는 경우, 사전 로드 표는 두 에셋을 모두 로드하는 데 필요한 엔트리를 포함하므로 크기가 커질 수 있습니다. 두 에셋이 모두 세 번째 에셋을 참조하는 경우 두 에셋의 사전 로드 표에는 세 번째 에셋을 로드하기 위한 엔트리가 포함되며, 이때 참조된 에셋이 어드레서블인지 동일한 에셋 번들에 있는지 여부는 상관 없습니다.
예를 들어 한 프로젝트의 에셋 번들에 두 개의 에셋(PrefabA
및 PrefabB
)이 있고 이 두 프리팹은 모두 세 번째 프리팹(PrefabC
)을 참조하는데, 이 프리팹은 크기가 크고 여러 컴포넌트와 다른 에셋에 대한 레퍼런스를 포함하고 있습니다. 이 에셋 번들에는 두 개의 사전 로드 표가 있는데, 하나는 PrefabA
용이고 다른 하나는 PrefabB
용입니다. 이 표에는 해당 프리팹의 모든 오브젝트에 대한 엔트리뿐만 아니라 PrefabC
의 모든 오브젝트 및 PrefabC
가 참조하는 모든 오브젝트에 대한 엔트리도 포함되어 있습니다. PrefabC
를 로드하는 데 필요한 정보는 결국 PrefabA
와 PrefabB
모두에 대해 중복됩니다. 이는 PrefabC
가 에셋 번들에 명시적으로 추가되었는지 여부에 관계 없이 발생합니다.
프로젝트에서 에셋을 구성하는 방식에 따라 에셋 번들의 사전 로드 표는 크기가 크고 중복된 엔트리를 많이 포함할 수 있습니다. 이는 예제의 PrefabC
와 같이 복잡한 에셋을 모두 참조하는 로드 가능한 에셋이 여러 개 있는 경우에 해당됩니다. 사전 로드 표의 메모리 오버헤드가 문제인 것으로 판단되면 프로젝트에서 로드 가능한 에셋을 구조화하여 복잡한 로딩 종속성을 줄일 수 있습니다.
에셋 번들 종속성 로드
어드레서블 에셋을 로드하면 그 종속성을 포함하는 모든 에셋 번들도 로드됩니다. 에셋 번들 종속성은 한 번들의 에셋이 다른 번들의 에셋을 참조할 때 발생합니다. 머티리얼이 텍스처를 참조하는 경우를 예로 들 수 있습니다. 자세한 내용은 에셋 및 에셋 번들 종속성을 참조하십시오.
어드레서블은 번들 수준에서 번들 간 종속성을 계산합니다. 한 에셋이 다른 번들에 있는 오브젝트를 참조하는 경우 전체 번들은 해당 번들에 대한 종속성을 갖습니다. 따라서 자체 종속성이 없는 첫 번째 번들의 에셋을 로드하더라도 두 번째 에셋 번들은 메모리에 로드됩니다.
예를 들어 어드레서블 에셋 RootAsset1
및 RootAsset2
를 포함하는 BundleA
가 있다고 가정해 보겠습니다. RootAsset2
는 BundleB
에 있는 DependencyAsset3
을 참조합니다. RootAsset1
은 BundleB
를 참조하지 않더라도 BundleB
에 종속됩니다. RootAsset1
이 BundleB
를 참조하는 BundleA
에 있기 때문입니다.
필요 이상의 번들을 로드하지 않도록 하려면 에셋 번들 간의 종속 관계를 최대한 단순하게 유지하십시오. 종속성을 확인하려면 빌드 레이아웃 보고서를 사용할 수 있습니다.