[C++로 개발하는 언리얼] 3장. 메모리 관리와 스마트 포인터
.
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 파일 결과 검사. 분석 유형에 따라 결과도 달라짐.
.
.
.