
Thick Pointer (TWeakObjectPtr / TStrongObjectPtr)
TWeakObjectPtr: 약한 참조를 통해 객체를 참조하며, 객체가 소멸되면 nullptr로 자동 변환됩니다.
TStrongObjectPtr: 강한 참조로, 참조가 유지되는 동안 객체는 소멸되지 않습니다.UObject 포인터
- UObject * : 포인터는 수동으로 관리되는 것이 아니라, 언리얼의 가비지 컬렉션 시스템에 의해 관리됩니다.
- UObject를 참조하는 변수들이 많아질수록 참조(레퍼런스)가 늘어나고, 해당 오브젝트는 아무 참조도 없을 때 가비지 컬렉션 대상이 됩니다.
가비지 컬렉션 정책:
- 언리얼은 레퍼런스 카운트 방식보다는 참조 그래프를 유지하며, 참조가 끊어진 객체를 주기적으로 정리하는 가비지 컬렉션을 수행합니다.
- UPROPERTY() 매크로를 사용한 포인터들은 자동으로 참조관리 대상에 포함되어, 참조가 계속 유지되면 객체가 소멸되지 않도록 돕습니다.
- AddReferencedObjects()라는 가비지 컬렉션의 직접 참조 관리 콜백도 존재합니다.
요약:
- 언리얼은 UObject와 기타 참조 대상 객체들의 레퍼런스 수를 명시적으로 관리하는 대신, 참조 그래프를 통한 가비지 컬렉션 시스템으로 메모리를 관리합니다.
- UPROPERTY()로 선언된 포인터는 언리얼이 내부적으로 참조를 추적하여, 객체가 필요 없을 때 소멸시킵니다.
참조 그래프 :
- 객체 탐색 시작점 지정
엔진은 가비지 컬렉션을 수행할 때 '루트' 객체들(Root Set)에서 시작하여, 이들로부터 참조하는 객체들을 재귀적으로 탐색합니다.
예를 들어, UObject 콜렉션에 등록된 루트 객체들이 시작점이 됩니다.2. 객체 탐색과 참조 추적
- 엔진은 UObject 내부 또는 UProperty 포인터를 통해 참조하는 대상 객체들을 검사합니다.
- 각 객체가 참조하는 다른 객체들을 트리 또는 그래프 구조에 어떻게 연결하는지 기록합니다.
- 이 과정에서 포인터 또는 내부 참조 테이블을 통해 참조 관계를 추적합니다.
참조 그래프의 표현과 저장 :
- 참조 관계는 내부적으로 그래프 데이터 구조(일반적으로 인접 리스트 또는 트리 구조)로 저장됩니다.
- 엔진은 이 데이터를 바탕으로, 어떤 객체들이 살아 있는지, 어떤 객체들이 더 이상 참조되지 않는지 판단합니다.
가비지 컬렉션에 따른 그래프 업데이트
- 가비지 컬렉션 수행 시, 이 참조 그래프를 기반으로 Marking(활성 객체 표시)과 Sweeping(불필요한 객체 제거) 과정이 진행됩니다.
- 참조 그래프에서 참조가 끊어진 객체들은 미리 표시되거나 삭제됩니다.
개발자가 볼 수 있는 참조 그래프
- 언리얼 엔진은 일부 도구와 콘솔 명령어를 통해 객체 참조를 실시간으로 검사하거나 디버깅할 수 있는 기능을 제공합니다. 예를 들어, MemReport 또는 ObjList 명령어를 통해 객체의 참조 상태를 확인할 수 있습니다.
요약
- 참조 그래프는 루트 객체에서 시작하여 재귀 탐색으로 생성됩니다.
- 엔진이 내부 구조를 통해 객체 간 포인터와 참조 관계를 기록하고 저장합니다.
- 이 그래프를 이용하여 가비지 컬렉션이 수행되며, 참조가 끊어진 객체들이 식별됩니다.