UDN
Search public documentation:
MemoryProfilingHomeKR
English Translation
日本語訳
中国翻译
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
日本語訳
中国翻译
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
UE3 홈 > 퍼포먼스, 프로파일링과 최적화 > 메모리 사용량과 프로파일링
메모리 사용량과 프로파일링
문서 변경내역: Jeff Wilson 작성. 홍성진 번역.
개요
메모리 디버깅: 단계별
- 스태틱 메시가 너무 많은 레벨.
- 프로젝타일과 파티클을 너무 많이 만들어 내는 AI.
- 메모리 할당이 과한 코드.
- 예산: 메모리를 뭐에 쓸 것인가.
- 모든 애셋이 최적화되어 불필요한 리퍼런스가 없는지 확인.
- 게임 실행을 유지하기에 (단편화용) 버퍼가 충분한지 확인.
메모리 트래킹 툴과 기술
STAT LEVELS
STAT LEVELS
명령은 메모리에 로드된 레벨이 몇이나 되는지 확인할 때 사용합니다.
- Red - 레벨이 로드되어 표시중입니다.
- Orange - 레벨이 표시되려는 프로세스에 있습니다.
- Yellow - 레벨이 로드되었으니 표시되지 않습니다.
- Blue - 레벨이 언로드되었으나 여전히 메모리에 있으며, 가비지 컬렉션 발생시 정리됩니다.
- Green - 레벨이 언로드되었습니다.
- Purple - 레벨이 로드전(preloading)입니다.
STAT MEMORY
STAT MEMORY
명령은 레벨의 애셋 메모리 사용량의 기본적인 개요를 제공합니다.
- Audio Memory 오디오 메모리
- Novodex Allocation 노보덱스 할당
- Animation 애니메이션
- Vertex Lighting 버텍스 라이팅
- StaticMesh Vertex/Index 스태틱 메시 버텍스/인덱스
- SkeletalMesh Vertex/Index 스켈레탈 메시 버텍스/인덱스
- Decal Vertex/Index 데칼 버텍스/인덱스
- VertexShader 버텍스 셰이더
- PixelShader 픽셀 셰이더
- Texture Pool Size 텍스처 풀 크기
- FaceFX
Content Comparison
게임명 ContentComparisonCommandlet
주: 이 작업은 야밤에 돌리는 것이 좋습니다.
애셋의 전체 메모리를 분석하여 비교하기 좋게 다수의 "주요" 범주로 나눠 줍니다.
이들은 현재 BaseEditor.ini 에 위치해 있으며, 다음과 같습니다:
[ContentComparisonReferenceTypes] +Class=AnimSet +Class=SkeletalMesh +Class=SoundCue +Class=StaticMesh +Class=Texture2D이 속성을 사용하는 이유는 보통 메모리 사용량의 대다수를 대표해 주는 데다가, 애셋 간의 비교가 가장 쉽기 때문이기도 합니다. 예로 N 무기가 있다 칩시다. 작은, 중간, 큰 무기로 나눠볼 수 있겠죠. 일반적으로 작은 무기가 큰 무기보다 비싸지는 말아야 될 겁니다. 그래서 각 무기의 비용을 시각화시켜 볼 수 있으면 비용이 맞는지 쉽게 판단해 볼 수 있습니다. 좀 더 일반적으로, 애셋 종류에 따른 표준 편차를 낮추는 게 좋을겁니다. 예로, 비슷한 캐릭터가 N개 있다면, 스켈레탈 메시 측면에서 다른 캐릭터보다 한 캐릭터의 비용이 1.5배에서 2배 정도까지 차이가 나게 되면 좋지 않을 겁니다. 한 캐릭터 비용이 다른 것보다 쎄지는 이유는 여럿 있습니다만, 그 중 일부는 단순히 무지에서 비롯된 겁니다. 이 커맨드릿의 아이디어는 비용을 목록화시켜서 기대치에 맞아 떨어지는지 확인해 보자는 것입니다. 분리물(outlier)을 조사해 보는 데도 좋겠습니다. ContentComparisionCommandlet 이 살펴볼 클래스를 설정해 주려면, DefaultEditor.ini 의 ContentComparisonClassesToCompare 부분을 수정하십시오.
콘텐츠 막대그래프
어떻게 15메가 사운드가 항상 로드된다는걸 알게 되었습니다. 근데 어떤 사운드들인지? "listsounds" 를 해 보면 사운드가 수백개씩 떠서, 어느건지 알아보기가 정말 힘듭니다. 로드된 텍스처가 수백개쯤 될 때는 텍스처도 마찬가지겠습니다. 메모리에 어떤 종류 의 사운드가 있는지 고수준으로 표시해 주면 시간 절약을 많이 할 수 있을 겁니다. 퍼센트만 맞으면, 좋은게 좋은겁니다. 근데 사운드 예산의 40%가 발소리에 쓰이고 있는걸 확인했다! 바로 최적화 시작입니다! MemLeakCheck 와 xls 스프레드 시트를 조합해서 막대그래프를 만듭니다. 사운드와 텍스처에 사용할 수 있는 샘플 .xls 파일입니다: SoundTextureHistograms.xlsx 레벨을 로드하고서 해 줄 작업은:- MemLeakCheck
- .xls의 SoundData 탭에 Sounds 목록을 복사해다 붙입니다.
- .xls의 TextureData 탭에 Textures 목록을 복사해다 붙입니다.
- .xls가 범주를 나눠 해당 범주별로 메모리 사용량을 나타내 줍니다.
엔진 메모리 풀
- Name Table
- Octree
- RB_BodyInstance Pool (c.f. DISABLE_POOLED_RB_INSTANCES)
- RB_ConstraintInstance Pool (c.f. DISABLE_POOLED_RB_INSTANCES)
- Static Mesh Collision Scale
- Render Thread 상의 Static Draw 리스트
- EmitterPool 을 사용중이라면 Particles
- DecalManager 를 사용중이라면 Decals
핫 스팟 보고서
MemLeakCheck 트래킹
텍스처 풀
- Streaming Fudge Factor: 스트리밍 퍼지(임시) 팩터, 가급적 1.0f 에 가까울 수록 좋습니다.
- Over Budget: 예산 초과, 가급적 0.0f 에 가까울 수록 좋습니다.
DefaultEngine.ini
에서:
[TextureStreaming] PoolSize=120
메모리 단편화
리퍼런스된 애셋 찾기
Memleakcheck
는 다량의 기본 게임 데이터를 [ProfileDirectory:Platform-specific]/MemLeak
안에 텍스트 파일로 출력합니다.
최소한 이를 통해 스켈레탈 메시, 애님세트, 사운드 등의 오브젝트 목록에 대한 스냅샷을 보여줄 것입니다. 기본적인 스냅샷이 생기면, 불필요한 애셋이 로드되지는 않았나 훑어보면 됩니다. 그렇다면 뭐가 그것을 리퍼런스했는지 추적해 내려가서 그 리퍼런스를 제거하는 것이 해결책입니다.
아래는 실전 사례입니다...
OBJ LIST CLASS=SKELETALMESH:
로드된 스켈레탈 메시를 크기별로 정렬하여 나열합니다. MEMLEAKCHECK
에도 이 정보가 포함되나 알파벳 순 정렬이기에 최적화할 콘텐츠를 찾기는 어렵습니다.
LISTSOUNDS:
로드된 사운드큐를 전부 나열합니다. MEMLEAKCHECK
에도 이 정보가 포함되나 알파벳 순 정렬이기에, 최적화할 콘텐츠를 찾기는 어렵습니다.
OBJ LIST CLASS=STATICMESH:
Lists all StaticMeshes loaded, sorted by size.
LISTANIMSETS:
로드된 애님세트 전부를 크기별로 정렬하여 나열합니다. MEMLEAKCHECK 에도 이 정보가 포함됩니다.
OBJ REFS:
애셋이 로드되는 이유를 알아내기에 가장 좋은 방법은 OBJ REFS
명령입니다. 이 명령은 PC 에서만 실행됩니다. 재귀 함수때문에 딥 스택이 필요한데, UE3 콘솔 버전에서는 거의 크래시가 나기 때문입니다.
문제되는 애셋이 로드되는 지점까지 플레이한 다음, 이렇게 입력하십시오: OBJ REFS CLASS= NAME=
예를 들어:
OBJ REFS CLASS=SKELETALMESH NAME=BIG_OGRE_2그러면 이 애셋을 끌어들이는 리퍼런스 체인이 무엇인지 표시됩니다:
Log: Shortest reachability from root to SkeletalMesh COG_Bolo_Grenade.Frag_Grenade: Log: SkeletalMesh COG_Bolo_Grenade.Frag_Grenade [target] (root) (standalone) Log: SkeletalMeshComponent GearGame.Default__GearProj_FragGrenade:COGGrenadeMesh0 (root) (ObjectProperty Engine.SkeletalMeshComponent:SkeletalMesh) Log: Class GearGame.GearProj_FragGrenade (root) (standalone)위의 예제에서, Frag_Grenade 메시가 GearProj_FragGrenade 네이티브 클래스의 default properties 에서 리퍼런스되고 있습니다. 그 이상의 리퍼런스가 있을 수 있는데, 그런 경우에는 한 번에 하나씩 처리해 줘야 합니다. 애셋이 잘못 로드되는 이유에 대해 저희가 알아낸 바로는:
- 애셋이 네이티브 클래스에 의해 리퍼런스되었습니다.
- UnrealScript 코드가 default property 를 구하기 위해 (애셋을 리퍼런스하는) 클래스를 리퍼런스하였습니다:
Asset = class'MyGameContent.Pawn_BigOgre'.default.Mesh.PhysicsAsset;
- Touch 키즈멧 이벤트 (SeqEvt_Touch) 가 그 ClassProximityTypes 또는 IgnoredClassProximityTypes 배열의 클래스를 리퍼런스합니다.