daisy0461 2024. 1. 3. 23:41

GC( GarbageCollection)를 위한 객체 저장소

  • 관리되는 모든 Unreal Object의 정보를 저장하는 전역 변수: GUObjectArray
  • GUObjectArray의 각 요소는 Flag가 설정되어 있다.
  • GC가 참고하는 Flag (물론 다른 Flag도 있다.)
    Garbage Flag: 다른 Unreal Object로부터 참조가 없어서 회수 예정인 Object
    RootSet Flag: 다른 Unreal Object로부터 참조가 없어도 회수하지 않는 Object
  • GC는 GUObjectArray에 있는 Flag를 확인해 회수할 Object를 파악 후 메모리에서 제거함.

GUObjectArray 구

 

GC의 메모리 회수 방식

  • GC는 지정된 시간에 따라(설정에서 변경 가능) 주기적으로 메모리 회수( Default = 60s)
  • Garbage Flag로 설정된 Object를 파악하고 메모리를 안전하게 회수한다.
  • Garbage Flag는 자동으로 설정된다.
  • Unreal은 C++과 다르게 생성된 Object를 delete로 바로 삭제가 불가능하고 GC가 회수하도록 해야한다.
  • ForceGarbageCollection함수를 통해 회수 가능
  • 개발 중 Destory를 자주 쓰는데 이도 결국 GC에 위임해서 메모리를 회수하게 된다.

 

 

RootSet Flag 설정 방법

  • AddToRoot함수를 호출해 RootSet Flag를 설정할 수 있다.
  • 제거를 위해선 RemoveFromRoot함수 호출하면 된다.
  • 이런 설정 방법은 권장되진 않는다.

 

Unreal Object를 회수되지 않게 설하는 방법

  • Unreal Engine 방식으로 참조를 설정한 Unreal Object면 회수되지 않는다.
    ex)UPROPETRY로 참조된 Unreal Object, AddReferencedObject함수를 통해 설정한 Unreal Object
  • RootSet Flag로 지정된 Unreal Object면 회수되지 않는다.

 

언리얼 오브젝트를 통한 포인터 문제의 해결

  • 메모리 누수 문제
    언리얼 오브젝트는 가비지 컬렉터를 통해 자동으로 해결
    C++은 직접 메모리 관련해서 신경써야한다. (스마트 포인터 사용)

  • 댕글링 포인터 문제 (포인터가 해제된 메모리 영역을 가리키는 것)
    언리얼 오브젝트는 이를 탐지하기 위해 ::IsVaild()를 제공함.
    C++ 오브젝트는 직접 신경써야한다. (스마트 포인터 사용)
  • 와일드 포인터 문제(적절한 타입의 유효한 객체를 가리키고있지 않는 포인터)
    언리얼 오브젝트는 UPROPERTY() 속성을 지정하면 자동으로 nullptr로 초기화한다.
    C++오브젝트의 포인터는 직접 nullptr로 초기화해야한다. or 스마트 포인터 사용

 

언리얼 오브젝트의 관리 원칙

  • 생성된 언리얼 오브젝트를 유지하기 위해 레퍼런스 참조 방법을 설계해야한다.
    언리얼 오브젝트 내의 언리얼 오브젝트 : UPROPERTY 사용
    일단 C++ 오브젝트 내의 언리얼 오브젝트 : FGCObject 상속 후 구현
  • 생성된 언리얼 오브젝트는 강제로 지우려고 하면 안된다.
    참조를 끊는다는 생각으로 설계
    CG에게 회수 재촉은 가능하다. -> ForceGarbageCollection 함수 사용
    Destory함수도 결국 GC에 위임하는 동작이다.

Unreal GC Cycle 주기 변환 방법

Project Setting에서 Garbage Collection -> General -> Time Between Purging Pending Kill Objects를 변경하면 된다.
지금은 61.0999~로 설정되어 있다.