UE5 가비지 컬렉션 시스템
UE5 GC 개요
섹션 제목: “UE5 GC 개요”UE5는 .NET/Java처럼 자동 GC를 제공하지만, UObject를 상속하는 클래스에만 적용됩니다. UObject가 아닌 일반 C++ 객체는 new/delete로 수동 관리합니다.
GC 동작:
- 마킹: 루트셋(Root Set)에서 도달 가능한 모든 UObject 탐색
- 스위핑: 도달 불가 UObject를
ConditionalBeginDestroy()호출 후 삭제
루트셋과 참조 유지
섹션 제목: “루트셋과 참조 유지”// UPROPERTY()가 없으면 GC가 수집할 수 있음UCLASS()class AMyActor : public AActor { GENERATED_BODY()
// GC에 의해 추적됨 (안전) UPROPERTY() UMyComponent* SafeComponent;
// GC에 의해 추적되지 않음 (위험) UMyComponent* UnsafeComponent; // 수집 후 dangling pointer!};항상 UObject 포인터 멤버에는 UPROPERTY()를 붙이세요.
AddToRoot / RemoveFromRoot
섹션 제목: “AddToRoot / RemoveFromRoot”UObject를 GC에서 영구 보호합니다.
// GC 수집 방지 (전역 싱글턴, 플러그인 등)MyObject->AddToRoot();
// 보호 해제 (메모리 누수 주의)MyObject->RemoveFromRoot();
// 루트에 있는지 확인if (MyObject->IsRooted()) { ... }TWeakObjectPtr — 약한 참조
섹션 제목: “TWeakObjectPtr — 약한 참조”GC가 객체를 수집해도 dangling pointer가 되지 않고 nullptr이 됩니다.
TWeakObjectPtr<AActor> WeakTarget;
void SetTarget(AActor* Target) { WeakTarget = Target;}
void Update() { // Get()으로 유효성 확인 if (AActor* Target = WeakTarget.Get()) { // 유효한 경우에만 사용 FVector Dir = Target->GetActorLocation(); } // WeakTarget.IsValid() 도 사용 가능}TObjectPtr (UE5.0+)
섹션 제목: “TObjectPtr (UE5.0+)”UPROPERTY()와 함께 사용하는 타입 안전 포인터입니다.
UPROPERTY()TObjectPtr<UStaticMeshComponent> MeshComp;
// 할당MeshComp = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
// nullptr 체크if (IsValid(MeshComp)) { ... }GC 주기와 강제 실행
섹션 제목: “GC 주기와 강제 실행”// GC 주기 설정 (초, 기본값 60초)// DefaultEngine.ini:// gc.TimeBetweenPurgingPendingKillObjects=30
// 코드에서 강제 GC (씬 전환 등에 사용)GEngine->ForceGarbageCollection(true);
// 비동기 GC (덜 블로킹)if (GEngine) GEngine->ForceGarbageCollection(false);IsValid vs nullptr 체크
섹션 제목: “IsValid vs nullptr 체크”// 잘못된 방법: nullptr만 체크하면 pending kill 상태 놓침if (MyActor != nullptr) { MyActor->DoSomething(); } // 위험
// 올바른 방법: IsValid()로 pending kill 포함 검사if (IsValid(MyActor)) { MyActor->DoSomething(); }
// 또는if (MyActor && !MyActor->IsPendingKill()) { ... }일반 구조체/클래스의 메모리 관리
섹션 제목: “일반 구조체/클래스의 메모리 관리”// UObject가 아닌 클래스는 스마트 포인터 사용TSharedPtr<FMyData> SharedData = MakeShared<FMyData>();TUniquePtr<FMyHelper> Helper = MakeUnique<FMyHelper>();TWeakPtr<FMyData> WeakRef = SharedData;
// 게임플레이 코드: TSharedPtr 남용 주의 (스레드 안전 오버헤드)// 단일 소유권: TUniquePtr// 공유 소유권: TSharedPtrUPROPERTY()가 없는 UObject 포인터는 GC 대상 — 반드시 붙일 것TWeakObjectPtr로 소유 없는 참조,IsValid()로 항상 유효성 검사AddToRoot는 전역 싱글턴 등 예외적 경우에만 사용 (누수 주의)- 씬 전환 후
ForceGarbageCollection으로 메모리 즉시 해제 - UObject가 아닌 객체는
TUniquePtr/TSharedPtr로 관리