TECHARTNOMAD | TECHARTFLOWIO.COM

TECH.ART.FLOW.IO

【번역】 언리얼 엔진 비디오 메모리 누수 찾기 솔루션 공유 - 툴 및 사용법

jplee 2024. 12. 15. 20:49

작성

강의 계획서

  • LLM(Low Level Memory)
  • Memreport -full
  • Unreal Insights
  • Tracing_malloc

Linux에서 메모리 보기:

Pid용 #2254
watch -n 1 -d 'cat /proc/2254/status | grep VmRSS'
가상 메모리 제한 방법: -v <가상 메모리 크기> 사용할 수 있는 최대 가상 메모리 양을 KB 단위로 지정합니다.

패킹후 메모리 분석:

패킹 방식에 따라 프로그램 메모리 최적화 방법도 다르기 때문에 Shipping 패키지에 DebugFile을 포함하여 메모리 사용 상황을 분석할 수 있습니다.

언리얼 프로젝트 셋업

UE 메모리 할당 방법:

일반적으로 사용되는 UE5 가상 엔진 메모리 분배기를 비교

일반적인 FMalloc 유형 및 시스템 지원

언리얼 엔진의 공식 메모리 분석 툴입니다:

一、LLM(Low Level Memory):

LLM(로우 레벨 메모리 트래커)은 4.18부터 도입된 새로운 메모리 통계 도구로, 멤리포트 통계보다 더 상세하고 정확하지만 MallocProfiler만큼 오버헤드가 많지 않습니다.
관련 코드는Engine\Source\Runtime\Core\Public\HAL\LowLevelMemTracker.h 와 Engine\Source\Runtime\Core\Private\HAL\LowLevelMemTracker.cpp
개발 및 디버그 패키지는 LLM이 켜진 상태에서 LLM을 자동으로 컴파일하지만, 런타임에 LLM의 기능을 사용하려면 시작 명령줄 -LLM -LLMCSV를 추가해야 합니다.

  • -LLM:런타임에 LLM 통계 열기
  • -LLMCSV:메모리 통계를 CSV 파일로 출력하고, 이 파일은 Saved\Profiling\LLM 디렉터리에 저장됩니다.

런타임에 기본적으로 적용되도록 하려면 Target.cs 파일에 매크로 정의 LLM_AUTO_ENABLE=1을 추가하면 됩니다.

리소스 통계 분류가 카테고리별인지 특정 리소스별인지를 나타내는 명령줄 -LLTAGSETS도 있지만, 이를 사용하려면 컴파일 시 코드에서 LLM_ALLOW_ASSETS_TAGS 매크로를 켜야 합니다(현재 이 매크로는 Target.cs 파일에 추가할 수 없음).

  • -LLMTAGSETS=Assets:리소스 분류별 통계
  • -LLMTAGSETS=AssetClasses:리소스 카테고리별 통계

런타임 스위치 LLM 처리는 FLowLevelMemTracker::ProcessCommandLine 함수에 설명되어 있습니다.
참고:UE4 Low Level Memory Tracker 사용
두 개의 출력 CSV 파일이 있습니다:

  • LLMPlatform은 시스템 메모리 소비자에만 초점을 맞추고 있으며, 몇 가지 주요 범주가 있습니다: ProgramSize, FMalloc, LLMOverhead
  • LLM은 주로 엔진의 다양한 부분의 메모리 개방인 FMalloc 메모리의 소비자에 초점을 맞추고 있습니다.

UE는 Engine\Binaries\DotNET\CsvTools 디렉터리에서 명령을 사용하여 CSV 시각화 툴을 제공합니다:

PerfreportTool.exe -csvdir %CSV_DIR% -o ./Report -grapxml ./LLMReportGraphs.xml -reportxml ./LLMReportTypes.xml

二、Memreport -full

이 명령은 UE에서 현재 프레임의 모든 메모리 리소스를 익스포트할 수 있으며, 여기에는 모든 UObject, 분류된 컬렉션 컴포넌트, RHI 리소스, LLM이 켜져 있는 경우 LLM이 포함됩니다. 미사용에 대한 전체 텍스트 검색
메모리 누수의 정확한 원인을 파악하려면 시간이 오래 걸리고 여러 번 수동으로 실행해야 하며, 패키지화된 Memreport 보고서를 보고 에디터에서 실행하면 최적화되지 않은 메모리 정보가 추가됩니다.

두 Mem보고서의 차이를 분석합니다. 예를 들어, 이전과 이후의 Mem보고서의 차이를 분석합니다.

Memreport를 사용하여 현재 RHI 메모리(GPU 메모리)에서 각 MRQ 합성 후에 비디오 메모리 누수를 유발하는 TextureRenderTarget2D 매핑 리소스가 추가되는 것을 찾아서 확인합니다.

三、Unreal Insights

트레이스 인사이트는 메모리 메트릭의 이 부분에 대한 UE의 내장 성능 분석 툴로, 실제로 LLM 모듈에서 파생되며 프레임당 메모리 변화, 모든 종류의 태그, 모듈 메모리 상황을 볼 수 있지만 디스플레이는 가상 메모리이며 물리적 메모리 점유를 정확하게 찾지 못할 수도 있지만 고려의 정점에서 확실히 줄일 수 있습니다.그러나 피크 값을 고려하면 확실히 물리적 메모리를 줄일 수 있으며 빠르게 증가하는 가상 메모리에 대해서는 후속 조치를 취하고 이유를 분석하는 것도 고려할 수 있습니다.
편집기에 명령줄 메서드가 추가됩니다:

메모리 인사이트 편집기 분석:

문제점: 에디터에서 분석하려면 수동으로 GC를 켜야 하고, 도구 자체가 너무 많은 메모리를 사용하며, 트레이스 파일이 더 많은 공간을 차지합니다.

四、Tracing_malloc:

https://github.com/dpull/tracing_malloc

Tracing_malloc은 Linux C/C++용 메모리 분석기 및 메모리 누수 탐지기입니다.사용이 매우 쉽습니다:

  • 대상 실행 파일을 수정하거나 다시 컴파일할 필요가 없습니다.LD_PRELOAD 메서드를 통해 대상 프로세스에 주입하여 메모리 할당(예: malloc)을 모니터링합니다.
    밸그라인드 및 멤로액스에 비해 성능 비용이 낮습니다.UE 대규모 프로젝트에 사용할 수 있습니다.
    스택, 할당 크기 및 시간을 포함한 언프리트 메모리의 실시간 추적.
    시간 기반 메모리 할당을 쉽게 확인할 수 있는 시각적 분석 툴.

문제: 시각적 분석 도구의 버그, 공식적인 후속 유지 관리 없음

Linux용 메모리 분석 밸그라인드 도구:

이 툴은 UE 프로그램을 시작할 때 소요되는 시간을 20~50배 증가시키고, 시작 명령에 -RenderOffScreen을 추가하여 벌칸 스왑 체인이 너무 오래 대기하여 일련의 성능 문제를 유발하거나 애플리케이션이 응답하지 않는 것을 방지하며, 시작 명령에 -ansimalloc을 추가하여 메모리 풀의 Ansi 할당을 사용하여 메모리 누수 위치를 쉽게 찾을 수 있도록 합니다.

1: 멤체크 소개 멤체크는 프로그램의 메모리 관리 문제를 검사합니다.메모리에 대한 모든 읽기/쓰기 작업을 검사하고 모든 malloc/new/free/삭제 호출을 가로챕니다.따라서 멤체크 도구는 다음과 같은 문제를 감지할 수 있습니다:

Memcheck 유틸리티는 주로 다음과 같은 프로그램 오류를 확인합니다:

  • 초기화되지 않은 메모리 사용 (Use of uninitialised memory)
  • 확보된 메모리 사용 (Reading/writing memory after it has been free’d)
  • malloc이 할당하는 것보다 더 많은 메모리 공간 사용 (Reading/writing off the end of malloc’d blocks)
  • 스택에 대한 불법 액세스 (Reading/writing inappropriate areas on the stack)
  • 요청된 공간이 해제되었습니다(예: 메모리 누수). (Memory leaks – where pointers to malloc’d blocks are lost forever)
  • malloc/free/new/delete 신청 및 삭제 내보내기( malloc/new/new [] vs free/delete/delete [] 사용성 불일치 )
  • src와 dst의 중첩(memcpy() 및 관련 함수에서 src와 dst 포인터가 겹치는 경우)

2: 멤체크 오류 메시지 설명

(1)==3185== Use of uninitialised value of size 8         ==3185== at 0x108602: main (a.c:6)

초기화되지 않은 주소가 사용되는 경우 프로그램이 초기화되지 않은 포인터를 사용하고 있는지 확인해야 합니다.

 

(2)==3223== Invalid write of size 4        ==3223== at 0x108602: main (a.c:6)8        ==3223== Address 0x0 is not stack’d, malloc’d or (recently) free’d

이 오류의 원인은 값이 잘못된 주소에 기록되었기 때문이며, 프로그램이 초기화되지 않은 포인터에 값을 할당하고 있거나 포인터에 값이 할당되지 않았는지도 확인해야 합니다.

이 오류는 크기 4의 잘못된 읽기 오류와 함께 발생합니다.

(3)==3397== Conditional jump or move depends on uninitialised value(s)
==3397== at 0x108656: main (in /home/ciaiy/Desktop/codingSpace/c/free/a)

이 오류가 발생하는 이유는 변수를 사용하기 전에 변수가 초기화되지 않았기 때문입니다.

 

(4)==3886== Invalid free() / delete / delete[] / realloc()
==3886== at 0x4C2CE1B: free (vg_replace_malloc.c:530)
==3886== by 0x1086CD: main (a.c:10)

이 오류는 포인터가 가리키는 메모리가 더 이상 해당 메모리에 속하지 않기 때문에 내 소유가 아닌 공간을 확보하여 발생합니다.

 

(5)==3839== HEAP SUMMARY:==3839== in use at exit: 412 bytes in 1 blocks==3839== total heap usage: 2 allocs, 1 frees, 924 bytes allocated

프로그램이 종료된 후 힙 메모리를 분석하면 위의 팁과 같이 412바이트의 공간이 비어 있는 상태로 프로그램이 종료됩니다.

3: 크로스 플랫폼 메모리 분석 도구 닥터 메모리.

 

GitHub - DynamoRIO/drmemory: Memory Debugger for Windows, Linux, Mac, and Android

Memory Debugger for Windows, Linux, Mac, and Android - DynamoRIO/drmemory

github.com

 

닥터메모리는 초기화되지 않은 메모리에 대한 액세스, 주소 지정이 불가능한 메모리에 대한 액세스(할당된 힙 단위 외부, 힙 언더플로 및 오버플로 포함), 해제된 메모리에 대한 액세스, 이중 해제, 메모리 액세스 등 메모리 관련 프로그래밍 오류를 식별하는 메모리 모니터링 툴입니다.누수, (Windows의 경우) 누수 처리, GDI API 사용 오류, 예약되지 않은 스레드-로컬 메모리 슬롯에 대한 액세스 등입니다.

Windows, Linux, Mac 또는 Android의 상용 IA-32, AMD64 및 ARM 하드웨어에서 실행되는 수정되지 않은 애플리케이션 바이너리입니다.


원문

https://zhuanlan.zhihu.com/p/717874170?utm_psn=1851654461304467456