Unreal의 참조 카운팅 시스템 - UObject클래스로부터 파생된 클래스 객체들의 메모리을 관리하는 시스템
UObject로 부터 파생되지 않는 클래스의 경우(순수 C++클래스의 경우) - TsharePtr, TWeakPtr를 사용해야 한다.
메모리 할당(객체 생성)
Unreal에서 더 이상 참조하지 않는 메모리 포인터는 즉시 지워지거나 마킹이 되어 다음 차례의 가비리 컬렉션때 삭제된다.
Unreal에서 메모리가 관리되기 위해서는 NewObject<> 또는 SpawnActor<>을 통해 객체가 생성되어야 한다.
UObject 파생 클래스는 NewObject<>을 통해 객체가 생성된다.
AActor 파생 클래스는 SpawnActor<>을 통해 객체가 생성된다.
Unreal에서 객체들의 포함관계
Package -> World -> Level -> UObject
Package은 World을 갖고 World은 Level을 작고 Level은 UObject을 가진다.
따라서 Package가 Unreal에서는 최 상위 저장소라고 보며 된다.
ConstructObject<>( )함수도 객체을 생성하는 함수로 NewObject<>( )와 비슷한 함수로 파라미터을 좀 더 구체적으로 설정할 수 있는 함수이다.
하지만 대부분 NewObject<>( )로 충분하다.
메모리 해제(객체 파괴)
UObject 인스턴스는 참조 카운터가 0이 되면 가비지 컬렉션 대상이 된다.
만약 참조 카운터가 0이 되기전에 해당 객체을 삭제하고 싶다면 UObject::ConditionalBeginDestroy()함수을 호출해 주면 수동으로 메모리를 해제할 수 있다.
UObject* object { NewObject<UObject>( ... ) };
object->ConditionalBeginDestroy();
따라서 ConditionalBeginDestroy()호출하게 되면 오버라이드 가능한 BeginDestroy와 FinishDestroy 함수가 호출된다.
하지만 주의할 것은 참조 카운터가 0이 되지 않은 상태에서 ConditionalBeginDestroy()을 호출하면 다른 객체가 해당 객체을 참조하고 있는 상황이므로 문제가 발생할 수 있다. 따라서 ConditionalBeginDestroy()을 호출할려면 먼저 참조 카운터가 0임을 확인하고 호출해 주어야 한다.
메모리 추적을 위한 스마트 포인터 사용
C++에 표준 스마트 포인터가 존재하는 것처럼 Unreal에도 스마트 포인터가 존재한다.
Unreal에서는 TSharePtr을 사용한다.
하지만 UObject파생 클래스 객체들은 이미 자체적인 참조 카운트 방식을 사용하므로 TSharePtr을 사용할 수 없다.
만약 당신이 UObject파생 클래스 객체가 아닌 순수 C++클래스 객체의 메모리을 관리하고 싶다면 TSharedPtr와 TSharedRef은 좋은 선택이다.
(new키워드을 통한 메모리 할당 객체인 경우~)
- TSharedPtr : 스레드로부터 안전한 (ESPMode::ThreadSafe를 인자로 넘긴다면) 참조 카운트 포인터 타입으로, 공유 객체를 나타낸다. 참조 카운트가 없을 때 할당 해제 된다.
- TSharedRef : null이 불가능한 TSharedPtr이다. TSharedPtr로 변환이 가능하다.
- TScopedPointer : { } 블록에서 블록의 끝에서 자동으로 삭제되는 포인터
{
TScopedPointer<AActor> warrior(this);
} // 이곳에서 삭제됨
일반 C++ 클래스을 new로 메모리 할당하고 TSharedPtr로 감싸주는 방법
//C++ 표준 클래스의 메모리 할당 및 스마트 포인터 사용
class MyClass {};
TSharedPtr<MyClass> sharedPtr { new MyClass() };
TSharedPtr<MyClass> ptr { sharedPtr };
TArray은 UPROPERTY을 사용해야 메모리가 관리된다.
가비지 켈렉션 강제로 수행하는 방법
GetWorld()->ForceGarbageCollection(true);
'Unreal' 카테고리의 다른 글
언리얼 에디터에서 카메라 위치 북마크 하기 (0) | 2023.08.17 |
---|---|
WorldContextObject을 인자로 요구하는 C++함수을 블루프린트 노드로 만들기 (0) | 2023.08.17 |
에픽런쳐의 언리얼5.1와 GitHub에서 받아 빌드한 언리얼5.1 버전의 DDC 폴더 설정 (0) | 2023.08.16 |
언리얼의 리플렉션 기능을 이용하여 클래스나 구조체의 정보 얻기 (0) | 2023.08.14 |
언리얼에서의 메모리 할당 (0) | 2023.08.14 |