Unreal Engine/개념정리

언리얼 엔진의 GC(Garbage Collection)

KimGeon-U 2024. 12. 3. 17:38

C++을 사용한 WinAPI 및 D3DX 환경에서는 메모리 공간을 효율적으로 사용하기 위해 생성자 및 소멸자를 사용하여 메모리 누수를 방지하였습니다. 

언리얼 엔진을 통한 게임 개발시에는 생성한 객체 및 자원들을 개발자가 아닌 엔진에게 메모리 관리를 담당하여 개발자의 편의성 및 프로그램 메모리를 관리 및 최적화 하는 가비지 컬렉션(Garbage Collection)이 존재합니다.

이번 포스팅에서는 언리얼 엔진의 GC에 대해 알아보겠습니다.

 

 

Garbage Collection

GC는 동적으로 생성한 객체들이 저장되는 영역인 Heap영역에 메모리가 할당되어 있는 객체들을 대상으로 사용됩니다.

언리얼 엔진을 사용하는 환경에서의 장단점에 대해 알아보겠습니다.

 

 

 

언리얼 엔진에서의 GC 특징

  • 마크 앤 스윕(Mark and Sweep) 알고리즘을 기반으로 동작한다.
    • Mark : GC 루트에서 시작해 연결된 객체를 "사용 중"으로 마킹하는 단계
    • Sweep : 마킹되지 않은 객체를 해제한다.
  • UObject를 관리한다.
  • AddToRoot() 또는 RemoveFromRoot()를 사용하여 특정 객체를 GC루트로 추가/제거 할 수 있다.
    • 최초 탐색 목록으로 설정하여 메모리가 회수되지 않는다.
  • 관리되는 모든 언리얼 오브젝트의 정보를 저장하는 GUObjectArray 전역변수를 통해 관리하며, 각 요소에 설정된 Flag를 통해 RootSet, Garbage 플래그를 구분하여 시스템이 자동으로 회수한다.

 

마크 앤 스윕 (Mark and Sweep)

  1. 힙 영역에서의 최초 검색을 시작하는 루트 오브젝트를 표시한다.
  2. 루트 오브젝트가 참조하는 객체를 찾아 마크(Mark)한다.
  3. 마크된 객체로부터 다시 참조하는 객체를 찾아 마크하고, 이를 반복한다.
  4. GC가 더이상 참조하지않는 (마크되지 않은)객체들의 메모리를 회수한다.(Sweep).

※ 탐색하는 과정은 DFS(깊이 우선 탐색) 방식으로 이루어지며, 필요에 따라 BFS(너비 우선 탐색)으로 이루어진다.

※ 또한 해시 테이블을 사용하여 탐색 중 방문한 객체를 기록, UObject의 고유 식별자를 키로 저장하여 중복 탐색을 방지한다.

 

 

장점

  • 개발자가 아닌 엔진에게 메모리 관리를 담당하여, 논리적으로 메모리를 관리, 최적화를 할 수 있다.
  • 해제된 메모리에 대한 접근을 방지하여 개발자의 실수를 방지할 수 있다.
    • 메모리 누수(Leak) : delete를 사용하지 않아 힙에 메모리가 그대로 남아있을 때
    • Dangling : 이미 해제한 객체를 다시 한번 해제할려 할 때
    • Wild : 값이 초기화 되지않아 잘못된 주소(nullptr)를 가르킬 때 

단점

  • 개발자가 객체를 직접 소멸시에도 GC는 해당 객체를 Unreachable 처리 전까지는, 추적을 계속한다.
    • 오버헤드가 발생할 수 있다.
  • GC가 메모리는 해제하는 시간을 명확하게 파악하기 어렵다.
  • 언리얼 엔진의 GC는 UPROPERTY를 사용하지 못하는 일반 C++ 클래스는 관리하지 않는다.
    • 개발자가 FGCObject 클래스를 상속, AddReferenceObjects 함수를 구현하여 관리할 수 있다.

 

 

가비지 콜렉터의 구성 옵션

편집 - 프로젝트 세팅 - 엔진 - 가비지컬렉션 설정 옵션

 

언리얼5에서 추가된 GC의 기능

1. GC 병렬화 (Parallel Garbage Collection)

  • GC작업이 멀티스레드 환경에서 병렬로 수행하도록 최적화가 되어 처리 속도가 향상되었다.
  • 객체 참조 그래프 생성 및 탐색 과정에서 병렬처리가 이루어진다.

2. Incremental GC 성능 향상 (점진적 가비지 컬렉션)

  • GC작업을 여러 프레임에 걸쳐 나눠 수행하여 큰 규모의 객체 그래프에서도 GC로 인한 지연을 최소화한다.
  • gc.TimeLimit, gc.NumRetriesBeforeForcingGC와 같은 설정을 통해 GC가 실행되는 방식을 조절할 수 있다.

3. 클러스터 기반 GC

  • 객체를 클러스터 단위로 관리하여 관련 객체를 함께 처리할 수 있다.
  • 개별 객체마다 사용되던 GC 비용을 최소화 하여 성능을 향상시킬 수 있다.

그 외에도 다양한 기능들이 언리얼5에서 추가, 개선되었으며 공식 홈페이지의 학습 문서를 통해 확인할 수 있습니다.

 

 


출처 및 참고내역

 

https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-object-handling?application_version=4.27

https://dev.epicgames.com/community/learning/knowledge-base/ePKR/unreal-engine-garbage-collector-internals

https://dev.epicgames.com/community/learning/knowledge-base/xaY1/unreal-engine-primer-debugging-garbage-collection-performance