UDN
Search public documentation:
MemoryDebuggingKR
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
메모리 디버깅
메모리 디버깅 개요
단계별 메모리 디버깅
- Static Mesh를 너무 많이 가지고 있는 레벨.
- 발사체 및 입자를 너무 많이 만들어내는 AI.
- 메모리를 지나치게 많이 배정하는 코드.
- 예산: 무엇을 위해 메모리를 사용할지 결정합니다.
- 모든 자산이 최적화되어 있고 불필요한 참조를 가지고 있지 않도록 확인합니다.
- 게임이 계속 실행되기에 충분한 버퍼(단편화를 위한)를 가지고 있는지 확인합니다.
#define KEEP_TRACK_OF_NOVODEX_ALLOCATIONS 1
참조 케이스
레벨의 최적화
StatsSTAT LEVELS
Stat levels
를 실행하여 몇 개의 레벨이 메모리에 로드되어 있는지 확인하십시오.
- 초록: 언로드됨
- 빨강: 로드됨 (로드에 걸린 시간도 함께 표시)
- 파랑: 언로드되어 가비지 콜렉션 되는 중
- 노랑: 로드되었지만 보이지 않음
- 분홍: 로드할 준비중
STAT MEMORY
Stat Memory
는 레벨에서 자산의 메모리 사용에 대한 기본 윤곽을 제공합니다.
- 오디오 메모리
- Novodex 할당
- 애니메이션
- 정점 조명
- StaticMesh의 정점/인덱스
- SkeletalMesh의 정점/인덱스
- Decal의 정점/인덱스
- VertexShader
- PixelShader
- 텍스처풀의 사이즈
- FaceFX
- ListSpawnedActors
- ListLoadedPackages
- ListPrecacheMapPackages
- OBJ BULK
엔진 환경 설정
텍스처풀의 사이즈: 렌더 타겟을 제외한 모든 텍스처는 텍스처풀을 사용합니다. 여기에는 Lightmap도 포함됩니다 (정점 조명 대신에 Lightmap을 사용하는 것은 메모리 절약에 확실히 더 효과적입니다. Lightmap은 시스템의 메모리를 동요시키지 않기 때문입니다). 또 게임을 위한 텍스처풀의 사이즈가 최적화되어 있는지 확인하십시오.Stat Memory
는 사용되고 있는 텍스처풀의 수를 보여줍니다. 이를 바탕으로 게임에 가장 알맞은 수를 결정할 수 있습니다.
In *Engine.ini, [TextureStreaming] PoolSize=120빈번한 가비지 수집: 게임에 가비지 수집 을 더 자주 할 필요가 있다면, 아래의 설정을 사용하시기 바랍니다.
*Engine.ini에서, [Engine.Engine] TimeBetweenPurgingPendingKillObjects=10 (10초마다)
애니메이션 최적화
게임에서 AnimSet이 참조되면, 이는 AnimSet에 있는 애니메이션을 모두 로드합니다. 이 애니메이션 가운데 일부만 사용할 생각이라면 이것은 낭비입니다. AnimSet 내의 애니메이션이 전부 필요하지 않다면, 이를 몇 개의 하위 AnimSet으로 분할하여 필요할 때만 로드할 것을 권합니다. 예를 들면, 언제나 모든 무기 애니메이션이 필요하지 않은 한 여러가지 무기들이 각기 고유의 AnimSet을 갖도록 하는 것입니다. Matinee: Matinee 의 경우 최적화 문제가 더욱 심각해질 수 있습니다. 마티네의 시퀀스마다 또는 레벨마다 다른 AnimSet을 갖는다는 것은 워크플로에 따라서(예:각 Matinee 시퀀스를 각기 다른 사람이 담당하고 있는 경우) 매우 성가신 일이 될 수 있습니다. 레벨마다 하나씩의 AnimSet을 가지게 된다면 이상적이겠지만, 여러 개발자 그룹 (레벨 디자이너/애니메이터/스크립터) 사이에서 이를 관리하는 것은 매우 시간이 걸리는일입니다. InterpData의bShouldBakeAndPrune
(CL 259515) 플래그는 이러한 경우에 도움이 됩니다. 이는 해당 레벨을 위한 새 AnimSet을 만들어 그 레벨에서 사용되는 애니메이션만을 복제하고, 참조를 다시 링크합니다. 만일 그 AnimSet이 어떤 식으로든 쿡되거나 로드되었다면, 이 플래그는 무효화되어야 합니다. 같은 애니메이션이 복제될 것이기 때문입니다. 이 플래그는 굽거나 손질하고 있는 AnimSet이 레벨에 의해 로드될 필요가 없을 때 사용되어야 합니다. *Editor.ini 의 Cooker.MatineeOptions 섹션에서 bBakeAndPruneDuringCook 를 FALSE 로 설정하여 이 플래그를 글로벌로 무효화할 수 있습니다.
*Editor.ini에서, [Cooker.MatineeOptions] bBakeAndPruneDuringCook=false애니메이션 압축: 애니메이션 압축은 애니메이션의 메모리를 크게 절약할 수 있는 부분입니다. 자세한 내용은 애니메이션 압축 페이지를 참고하십시오.
참조 시스템
게임에서 레벨들이 거의 완성되어 가면, 이들을 모두 점검하여 꼭 필요한 자산들만이 로드되었는지 확인하십시오. Unreal Engine 3에서는 참조된 컨텐츠들은 게임에 모두 로드됩니다. 그리고 컨텐츠를 참조하는 직접 및 간접적인 방법들이 아주 많기 때문에, 자신이 깨닫지 못하는 사이에 대량의 자산을 로드하게 될 수 있습니다. 예를 들면 Skeletal Mesh를 참조하는 Pawn은 자동으로 그 Skeletal Mesh에 의해 참조된 AnimSet을 로드하게 됩니다. 따라서 모든 애니메이션(Pawn->Skeletalmesh->Animsets->Animations)도 로드됩니다. 이 연쇄관계는 메모리 면에서 위험할 수 있습니다. 게임이 서로를 참조하는 Actor들을 더 많이 가지게 되기 때문입니다. 여러분은 보통 레벨 디자이너들과 함께 작업하면서 로드되면 안될 것들, 또는 스트리밍 레벨들 간에 분할되어 한꺼번에 로드되면 안되는 것들이 로드되고 있는 것들이 있는지 결정할 것입니다. 해당 레벨에 등장하지 않는 적병의 메쉬가 그 좋은 예입니다. MEMLEAKCHECK:Memleakcheck
은 많은 양의 기본적인 게임 데이터를 [ProfileDirectory:Platform-specific]/MemLeak
에 하나의 출력 텍스트 파일로 인쇄합니다.
이는 최소한 Skeletal Mesh, AnimSet, 사운드 등등의 객체 리스트에 대한 스냅샷을 나타냅니다. 기본적인 스냅샷을 얻으면, 이것을 점검하여 불필요하게 로드된 자산이 있는지 확인할 수 있습니다. 불필요하게 로드된 자산이 있다면 그 자산이 누구에 의해 참조되었는지 추적해서 그 참조를 제거하는 것이 해결의 열쇠입니다.
다음은 사례 연구입니다...
OBJ LIST CLASS=SKELETALMESH:
로드된 SkeletalMesh들을 모두 사이즈 순으로 나열합니다. MEMLEAKCHECK
은 이 정보를 포함하고 있지만 알파벳 순으로 되어 있어, 내용을 능률적으로 찾기 어렵습니다.
LISTSOUNDS:
로드된 SoundCue들을 모두 사이즈 순으로 나열합니다. MEMLEAKCHECK
은 이 정보를 포함하고 있지만 이 역시 알파벳 순으로 되어 있어, 내용을 능률적으로 찾기 어렵습니다.
OBJ LIST CLASS=STATICMESH:
로드된 StaticMesh들을 모두 사이즈 순으로 나열합니다.
LISTANIMSETS:
로드된 AnimSet들을 모두 사이즈 순으로 나열합니다. 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 (근원에서 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 메쉬가 native 클래스인 GearProj_FragGrenade의 기본 속성에서 참조되고 있습니다. 참조가 하나 이상일 수 있다는 점을 유의하십시오. 이 경우 참조들을 한 번에 하나씩 처리해야 합니다. 자산이 정확하지 않게 로드되었다고 판정되는 데는 다음 몇 가지 이유가 있습니다:
- 자산이 native 클래스에 의해 참조되었습니다.
- UnrealScript 코드가 (그 자산을 참조하는) 클래스를 참조하여 거기서 기본 속성을 가져옵니다:
Asset = class'MyGameContent.Pawn_BigOgre'.default.Mesh.PhysicsAsset;
- Touch Kismet 이벤트(SeqEvt_Touch)가 ClassProximityTypes 또는 IgnoredClassProximityTypes 배열에 클래스를 참조합니다.
메모리 단편화
MEM STAT: 요약에 한함. MEM DETAILED: 할당자에 관한 유용한 정보를 인쇄합니다. 아래 의 플랫폼 섹션을 참고하십시오. 메모리 단편화를 위한 버퍼를 가지고 있는 것이 좋습니다.스택 메모리
스택 메모리는 메인 쓰레드에 상속됩니다. 쓰레드를 만들 때 그 사이즈를 지정할 수는 있지만, 내부적으로 쓰레드를 생성하는 라이브러리를 이용하는 경우 이는 메모리를 고려하지 않습니다.참조
- 메모리 개요: Memory Overview
- 메모리 할당: Memory Allocation
- 메모리 사용량: Memory Usage
- 메모리 프로파일러: Memory Profiler
- 메모리 추적: Memory Tracking
콘솔에서의 메모리
- Xbox360: MemoryDebugging (Xbox360)
- PS3: MemoryDebugging (PS3)
유용한 명령어들
- 모든 Stat 명령어에 대한 설명: Stats Descriptions
- 모든 콘솔 명령어: Console Commands