컨텐츠 검색
[UE5] _#13. 언리얼 엔진의 자원 관리

2025. 12. 17. 09:50Unreal Engine/개념

1. 메모리 관리 시스템 (Garbage Collection)

목적: 메모리 누수 방지 및 객체 생명주기 자동 관리

  • 기본 개념
    • Unreal Engine은 C++에 없는 독자적인 GC 시스템 사용
    • 사용되지 않는 UObject를 자동 회수
    • GC 이상 시 성능 저하·프리징 발생
  • 동작 방식
    • Mark-and-Sweep 알고리즘
      • Mark: 사용 중인 객체 표시
      • Sweep: 미사용 객체 제거
    • Root Set 기준 탐색
      • Root Set에서 직접/간접 참조된 객체만 생존
  • Root Set 관리
    • Root Set 객체는 GC 대상 아님
    • RF_RootSet 플래그로 보호
    • AddToRoot() : 강제 생존
    • RemoveFromRoot() : GC 대상 전환
  • 상태 관리 구조
    • 객체 상태는 여러 GC 플래그로 관리
    • RF_BeginDestroyed / RF_FinishDestroyed 플래그로 파괴 단계 추적
      • BeginDestroy(): 객체가 실제로 메모리에서 해제되기 전에 필요한 정리 작업을 수행
      • FinishDestroy(): 객체 소멸의 마지막 단계로, 이 함수 호출 후 객체의 메모리가 완전히 해제
    • 모든 UObject 상태는 GUObjectArray 전역 구조에 저장

2. 리플렉션 시스템 (Reflection)

목적: 사용자 정의 객체를 엔진·GC·에디터·블루프린트와 완전 통합

  • 리플렉션 정의
    • 실행 중 객체 구조·상태를 검사·조작하는 능력
    • Unreal이 사용자 객체를 “이해”하기 위한 필수 시스템
  • 필요성
    • C++ 자체에는 리플렉션 없음
    • 엔진 기능(GC, 에디터, BP)을 사용하려면 별도 정보 제공 필요
  • 구성 요소
    • UHT (Unreal Header Tool)
      • 리플렉션 매크로 분석
      • 메타데이터 및 자동 생성 코드 추가
    • 메타데이터 기반 엔진 인식
  • 필수 매크로
    • 클래스: UCLASS
    • 구조체: USTRUCT
    • 멤버 변수: UPROPERTY
    • 멤버 함수: UFUNCTION
    • 클래스 내부: GENERATED_BODY
  • 동작 규칙
    • 매크로 없는 C++ 객체는 엔진이 인식 불가
    • 매크로가 있어야:
      • GC 적용
      • 에디터에서 변수 수정
      • 블루프린트 노출 가능
  • 프로퍼티 제어
    • UPROPERTY로:
      • 읽기/쓰기 권한
      • 에디터 노출 여부
      • 수정 범위 설정 가능
    • 일부 GC 관련 플래그는 엔진 내부 전용

3. 엔진 통합 효과

결과: 사용자 객체의 엔진 레벨 일관성 확보

  • GC 자동 관리
  • 에디터 기반 데이터 수정 (HP, Name 등)
  • 블루프린트 노드 기반 로직 구성
  • 엔진 모듈과 동일한 생명주기·관리 체계 적용

4. Memory Pool

핵심

  • 빈번한 동적 할당/해제를 미리 확보한 메모리 블록으로 대체하는 기법

특징

  • 동일 크기 또는 제한된 크기의 객체를 미리 할당
  • new/delete, malloc/free 호출 최소화
  • 메모리 지역성(Cache locality) 향상
  • 실시간 시스템, 게임 루프에 적합

장점 / 단점

장점

  • 할당/해제 속도 매우 빠름
  • 힙 단편화 감소
  • 프레임 타임 안정화

단점

  • 메모리 낭비 가능성
  • 풀 크기 설계 실패 시 오히려 위험
  • 디버깅 난이도 상승

공통 / 차이점

  • RAII: 수명 관리 관점에서 보완 관계
  • GC: 풀은 수동·결정적, GC는 자동·비결정적
  • 스마트 포인터: 소유권 관리 / 풀은 할당 전략

활용

  • 총알, 파티클, 몬스터 스폰 시
  • spawn/destroy 대신 Object Pooling으로 전환
  • 프레임 드랍 감소 체감

 


5. 언리얼 엔진은 메모리 풀을 사용할까?

핵심

  • 언리얼은 내부적으로 강력한 커스텀 메모리 할당 시스템을 사용

특징

  • FMalloc 기반 전역 할당자
  • 플랫폼별 최적화 (Binned Allocator, Mimalloc 등)
  • UObject는 자체 풀링 + GC 연계
  • 일반 new/delete는 거의 사용되지 않음

장점 / 단점

장점

  • 게임 규모에 최적화
  • 개발자가 풀 직접 구현할 필요 감소
  • 멀티스레드 안전

단점

  • 내부 구조 복잡
  • 엔진 외부 C++ 코드와 개념 혼동 가능

공통 / 차이점

  • 전통적 메모리 풀보다 더 추상화된 엔진 레벨 풀
  • 사용자 정의 풀은 Non-UObject에서 여전히 유효

활용

  • UObject 생성 비용 큼 → 빈번 생성 회피
  • 액터는 풀링, 컴포넌트는 재사용 설계

6. 언리얼 엔진 스마트 포인터 종류

핵심

  • UObject용 / Non-UObject용 포인터가 명확히 분리

종류 & 특징

TUniquePtr

  • 단일 소유
  • RAII, 이동만 가능
  • Non-UObject 전용

TSharedPtr / TWeakPtr

  • 참조 카운트 기반
  • 순환 참조 주의
  • Non-UObject 전용

TSharedRef

  • 절대 null 불가
  • 안정성 강화 버전

TObjectPtr

  • UObject 전용
  • GC 친화적
  • UE5 표준

TWeakObjectPtr

  • UObject 약한 참조
  • GC 후 자동 무효화

장점 / 단점

장점

  • GC와 C++ 메모리 모델을 명확히 분리
  • 크래시 방지 설계

단점

  • 표준 C++과 혼용 시 학습 비용
  • 잘못 쓰면 성능 저하

공통 / 차이점

  • std::shared_ptr ≠ TSharedPtr
  • UObject에는 절대 std 스마트 포인터 사용 금지
  • GC 세계 vs RAII 세계의 경계선

활용

  • UI ↔ Player 연결 시 TWeakObjectPtr 사용
  • 순환 참조 문제 해결