C++ 메모리 관리의 문제점
할당 받은 메모리는 반드시 프로그래머가 직접 해제까지 해줘야 함.
이를 지키지 않으면 메모리 누수부터 여러 문제점이 생긴다.
가비지 컬렉션 시스템
프로그램에서 더 이상 사용하지 않는 언리얼 오브젝트를 자동으로 감지.
특정 상황에 회수하는 시스템
생성된 모든 언리얼 오브젝트 정보를 모아둔 저장소를 사용해서 추적
Mark-Sweep 방식의 가비지 컬렉션
- 저장소에서 최초 검색을 시작하는 루트 오브젝트에서 시작.
- 루트 오브젝트가 참조하는 개체를 찾아 Mark
- Mark된 개체로부터 해당 개체가 참조하는 개체를 찾아서 다시 Mark. 반복.
- 이제 저장소에서 Mark된 개체와 그렇지 않는 개체로 나뉨.
- 가비지 컬렉터는 저장소에서 Mark되지 않은 개체들의 메모리 회수(Sweep)
GUObjectArray
관리되는 모든 언리얼 오브젝트 정보를 저장하는 전역 자료구조.
GUObjectArray의 요소에는 가비지 컬렉션 관련 플래그 정보가 있음.
RootSet 플래그: 다른 언리얼 오브젝트로부터 참조가 없어도 회수 되지 않음.
Garbage 플래그: 다른 언리얼 오브젝트로부터 참조가 없어서 회수 예정.
GCCyle
지정된 주기마다 가비지를 몰아서 없앰. 이 주기를 GCCycle이라 함.
Project Settings > Garbage Collection에서 확인 가능.
언리얼 오브젝트 사용을 통한 C++ 로우 포인터 문제 해결
메모리 누수: 가비지 컬렉션 시스템을 통해 자동으로 해결.
댕글링 포인터: 언리얼에서는 IsValid() 함수를 제공함.
nullptr 예외처리만 하면 댕글링 포인터 문제가 발생할 수 있음.
와일드 포인터: 언리얼 오브젝트의 속성은 UPROPERTY() 매크로 작성시 자동 nullptr 초기화
UPROPERTY() 매크로를 작성하지 않은 속성은 초기화 되지 않으므로, 주의해야함.
언리얼 스마트 포인터 라이브러리
- TUniquePtr: 포인터의 소유권을 공유할 수 없음.
특정 오브젝트에게 명확하게 포인터 해지 권한을 주고 싶은 경우에 사용.
delete 구문 필요 없이 자동으로 소멸됨.
- TSharedPtr: 포인터의 소유권을 공유 가능함.
할당된 오브젝트 포인터가 여러 로직에서 공유되어 사용될 때 사용.
다른 함수로부터 할당된 오브젝트를 Out으로 받는 경우.
nullptr일 수도 있기에 주의.
- TSharedRef: TSharedPtr과 유사하지만 유효한 개체임을 항상 보장받음.
- TWeakPtr: TSharedPtr은 순환 참조 문제가 있음. 이를 개선한 포인터.
캐릭터와 인벤토리 사이의 상호 참조가 필요할 때.
TSharedPtr으로부터 생성. nullptr일수도 있기에 주의.