Unreal 엔진

[C++로 개발하는 언리얼] 3장. 메모리 관리와 스마트 포인터

원생계 2019. 12. 20. 01:00

.

3장. 메모리 관리와 스마트 포인터

NewObject<> 사용, 스마트 포인터 (TSharedPtr, TWeakPtr, TUniquePtr )

TUniquePtr 을 사용해 객체 추적하기.

UObject에서 파생되지 않은 C++클래스의 경우 TSharedPtr / TWeakPtr 참조 ㅣ카운트 참조 체크.

관리되지 않는 메모리 new/delete

malloc = 메모리 할당

new = 메모리 할당 + 생성자 호출

UAction* action = NewObject<UAction>( GetTransientPackage(), UAction::StaticClass() );

구동 원리

UAction::StaticClass() 는 객체의 기본 UClass* 가져옴. GetTransientPackage() 는 게임의 일시적인 패키지를 검색한다. 블루프린트에서 TSubclssOf<AActor> 를 이용해 인스턴스 선택도 가능

UObject 들은 참조 횟수 카운트 -> 가비지 컬렉션.

명시적 해제 요청은

ConditionalBeginDestroy();

UObject *o = NewObject< UObject >( ... );

o->ConditionalBeginDestroy();

메모리 관리 - 스마트 포인트 (TSharedPtr, TWeakPtr, TUniquePtr)

class MyClass {}; // UObject 상속받지 않은 네이티브 클래스.

TSharedPtr<MyClass> sharedPtr ( new MyClass() );

TSharedPtr : UObject 상속 클래스를 제외하고 모든 사용자 정의 C++ 객체를 참조 카운팅하는 유용한 C++ 클래스. (UObject 상속 클래스는(=NewObject)는 TSharedPtr 을 사용할 수 없다.)

TWeakPtr : 객체 삭제를 방지할 수 없는 속성을 가진 참조 카운트된 객체를 가리킴.

? 무슨 소리지...

Weak 포인터는 참조 횟수가 0으로 떨어지면 객체를 메모리에 유지X

Weak 포인터 아래 객체(?)가 수동으로 삭제될 때(ConditionalBeginDestroy() 로...) Weak 포인터는 NULL 참조가 된다. IsValid() 메소드로 유효성 체크.

if ( ptr.IsValid() ) // Weak 포인터 유효한지 확인.

{}

TSharedPtr 은 스레드 안전. UObject/파생 클래스는 사용 불가. 중요하니 두 번 강조.

원시 포인터는 TSharedPtr, TSharedRef, TWeakPtr 중 하나

UObject 는 TWeakObjectPtr, TStrongObjectPtr 또는 UPROPERTY() 를 가져야.

TUniquePtr 로 객체 추적하기

스코프 포인터는 블록 선언 끝에서 자동 삭제되는 포인터.

{

int x;

{

int y;

} // y 스코프 끝

} // x 스코프 끝

TUniquePtr<AWarrior> warrior( this );

언리얼 가비지 컬렉션 시스템과 UPROPERTY()

UCLASS() 선언된 클래스 멤버로 객체가 있으면 UPROPERTY() 로 선언해야 제대로 할당됨.

가령, TArray<> 가 있을 때, UPROPERTY() TArray<> 로 선언해야함.

UCLASS()

class MYPROJECT_API AWarrior : public AActor

{

UPROPERTY() TArray< FSoundEffect > Greets;

// TArray< FSoundEffect > Greets; // 제대로 할당되지 않음.

}

UPROPERTY() 선언은 엔진에 메모리 관리돼야 함을 알린다. 없으면 가비지 컬렉션 제대로 동작하지 않음.

> 가비지 컬렉션의 강제 수행

거의 할 필요 없는 작업이지만, 참조 카운트가 있는 매우 큰 텍스처를 해제할 경우는 있을 수 있음.

UObject를 메모리에서 해제하려면 ConditionalBeginDestroy() 호출하거나 객체 참조 카운트를 0으로 설정.

가비지 컬렉션 강제 구동은

GetWorld()->ForceGarbageCollection( true );

중단점과 단계적 코드 실행

버그 찾기와 콜 스택 사용

프로파일러를 사용해 핫 스팟 식별

최적화 코드 절을 파악할 수 있음.

구동 방법

1. 디버그 > 성능 프로파일러

2. 분석 유형 선택 > 시작

3. 샘플 수집 중지하려면 짧은 시간 후에 코드 중지.

!! 샘플 너무 많이 수집하며 로래걸림. 짧게 수집해야 함.

4. .diagsession 파일 결과 검사. 분석 유형에 따라 결과도 달라짐.

.

.

.

728x90
반응형