가비지 컬렉션은 더 이상 사용하지 않는 메모리를 알아서 치워주는 것과 같다고 할 수 있습니다.
이를 통해 개발자가 메모리 해제를 수동으로 처리하는 부담을 덜고, 메모리 누수나 댕글링 포인터와 같은 메모리 오류를 줄일 수 있습니다.
가비지 컬렉션은 마크 앤 스윕 알고리즘 방식으로 동작합니다.
이 알고리즘은 주기적으로 실행되며, 더 이상 프로그램에서 사용하지 않는다고 판단되는 UObject 들을 식별하여 메모리에서 제거합니다.
루트셋에서 시작 - 먼저 루트셋에 포함된 객체들을 식별합니다. - 이 객체들은 항상 살아있다고 간주되는 특별한 객체입니다. - 예를 들어, 게임 엔진 자체, 플레이어 컨트롤러 등이 루트셋에 포함될 수 있습니다. 이는 가비지 컬렉션 대상이 아닙니다. 청소 시, 절대 버려서는 안된느 물건으로 비유 할 수 있습니다.
마크 단계 - 도달 가능성 분석 - 루트셋 객체에서 시작해서 직간접적으로 참조하는 UObject를 마크 합니다. 이는 객체가 사용중임을 나타냅니다.
스윕 단계 - 메모리 회수 - 마크 단계가 완료되지 않은 객체들이 차지하고 있던 메모리를 회수합니다. 이 과정에서 해당 객체의 소멸자가 호출되고 메모리가 반환됩니다.
루트셋에서 직접, 간접(참조) 된 객체들을 가비지 켈렉션 대상에서 제외합니다.
UObject 에는 가비지 컬렉션 동작 방식을 제어하는 다양한 플래그가 존재합니다.
이 플래그들은 가비지 컬렉션의 동작에 중요한 정보를 제공하며, GUObjectArray라는 전역 배열에 저장된 각 객체 정보의 일부로 관리됩니다.
RF_RootSet - 이 플래그가 설정된 객체는 루트셋의 일부로 관리됩니다. - 즉 설정된 시점부터 가비지 컬렉션 대상이 아닙니다. AddToRoot() 함수를 통해 설정하고, RemoveFromRoot() 함수를 통해 해제 할 수 있습니다.
RF_BeginDestroyed - 객체의 BeginDestroy() 함수가 호출되었음을 나타냅니다. - 해당 함수는 객체가 실제로 메모리에서 해제되기 전에 필요한 정리 작업을 수행하는 함수입니다.
RF_FinishDestroyed - 객체의 FinishDostroy() 함수가 호출되었음을 나타냅니다. 해당 함수는 객체 소멸의 마지막 단계로, 이 함수 호출 후 객체의 메모리가 완전히 해제됩니다.
언리얼 엔진의 리플렉션 시스템
리플렉션이란 프로그램이 실행 중에 자신의 구조와 상태를 검사하고 수정할 수 있는 능력을 말합니다.
쉽게는 C++ 코드에 붙인 클래스/변수/함수 정보를 엔진이 알아볼 수 있게 만드는 시스템이라고 보면 됩니다.