Blog

ENGINEERING NOTE

[Unreal Engine] Garbage Collection

가비지 콜렉션(GC)은 더 이상 사용되지 않는 객체(메모리)를 자동으로 탐지하고 해제하여 메모리 누수를 방지하는 기술이다. C++, C와 같은 언어는 수동으로 메모리를 해제해야 하지만, GC를 사용하는 언어나 엔진에서는 이 작업을 자동으로 처리한다.GC의 주요 목적은

Unreal Engine

가비지 콜렉션의 정의

가비지 콜렉션(GC)은 더 이상 사용되지 않는 객체(메모리)를 자동으로 탐지하고 해제하여 메모리 누수를 방지하는 기술이다. C++, C와 같은 언어는 수동으로 메모리를 해제해야 하지만, GC를 사용하는 언어나 엔진에서는 이 작업을 자동으로 처리한다.

GC의 주요 목적은 다음과 같습니다:

  • 사용되지 않는 객체 탐지
  • 해당 객체의 메모리 해제
  • 메모리 누수 및 충돌 방지

대표적인 GC 알고리즘으로는 Mark and Sweep, Reference Counting, Generational GC 등이 존재한다.


언리얼의 가비지 콜렉션

언리얼 엔진은 일반적인 C++ 언어의 수동 메모리 해제 방식이 아닌, 자체적인 GC 시스템을 통해 UObject 기반 객체들의 메모리를 자동으로 관리한다. 이를 통해 복잡한 객체 참조 구조에서도 안정적인 메모리 관리를 가능하게 한다.

언리얼의 GC는 C++ 런타임 레벨이 아닌, 엔진 레벨에서 구현된 커스텀 GC로, 엔진 내부에서 관리되는 UObject만이 이 GC의 대상이 된다.

Mark and Sweep 알고리즘

언리얼 엔진의 GC는 Mark and Sweep 방식을 기반으로 동작한다.

이 방식은 크게 두 단계로 나뉜다:

Mark (표시 단계) 루트 객체(Root Object)에서 시작하여 연결된 모든 객체를 탐색하며 "사용 중"이라고 표시한다. 루트 객체는 GCRoot 또는 UProperty 등에서 참조되는 객체들이다.

Sweep (정리 단계) 마킹되지 않은 객체는 더 이상 참조되지 않는 것으로 간주하고, 해당 객체를 메모리에서 제거한다.

이 방식의 장점은 객체 간의 순환 참조(Circular Reference)에도 강하다는 점이다. Reference Counting 방식은 순환 참조를 탐지하지 못해 메모리 누수가 발생할 수 있지만, Mark and Sweep은 루트에서 도달할 수 없는 모든 객체를 제거하기 때문에 이 문제를 피할 수 있다.


UObject의 처리 방식

언리얼 엔진에서 GC의 대상이 되는 객체는 반드시 UObject를 상속해야 한다. 이 UObject는 GC 시스템에 의해 자동으로 추적되며 다음과 같은 방식으로 관리된다.

  • UPROPERTY()로 강한 참조를 유지할 때

GC가 추적 가능한 객체에서 UPROPERTY()로 연결된 객체는 자동으로 살아있다고 간주된다.

  • UObject::AddReferencedObjects()를 통해 참조를 수동 등록할 때

직접 참조를 추가하여 GC가 추적하도록 설정할 수 있다.

  • UObject::AddToRoot()로 루트 집합에 추가할 때

이 객체는 GC의 대상에서 제외되며 항상 살아있는 상태로 간주됩니다. (일반적으로는 불필요하며, 특수한 경우에만 사용)

위 조건 중 하나라도 충족하지 않으면, 다음 GC 사이클에서 해당 객체는 "unreachable"로 간주되고 제거된다.