언리얼 엔진(UE)은 식별 후 삭제 방식의 가비지 컬렉터를 사용하여 UObject 메모리를 관리합니다. 소프트 리얼타임 애플리케이션의 경우, 가비지 컬렉터에 한 가지 큰 단점이 있었습니다. 가비지 컬렉터가 어떤 오브젝트의 메모리를 회수할 수 있는지 결정하는 동안 게임플레이 히치가 발생할 수 있다는 것입니다. UE에서는 이 프로세스를 도달 가능성 분석이라고 합니다. UE는 항상 이 가비지 컬렉션 단계를 사용하여 한 프레임 안에 완료하려고 하는데, 이 단계는 모든 UObject 프로세싱, 특히 게임플레이를 일시적으로 정지시킵니다. 도달 가능성 분석에서 스캔해야 할 오브젝트가 많을수록 일시정지 시간이 길어지고, 그 결과 게임플레이 히치가 발생할 수 있습니다. 프로그래머는 다음과 같은 몇 가지 방법으로 히치를 피할 수 있습니다.
UObject 예산을 빠듯하게 유지합니다.
UObject 풀을 사용합니다.
노멀 게임플레이 중에 가비지 컬렉션을 비활성화합니다.
그렇지만, 이러한 해결책을 사용하면 코드 복잡도와 전체 프로젝트 비용이 증가합니다.
점진적 도달 가능성 분석
UE는 점진적 도달 가능성 분석을 사용하여 이를 개선합니다. 이제 사용자는 환경설정할 수 있는 프레임별 소프트 시간제한을 사용하여 가비지 컬렉터의 도달 가능성 분석 단계를 여러 프레임에 걸쳐 분할할 수 있습니다. 언리얼 엔진은 TObjectPtr 프로퍼티를 통해 도달 가능성 반복작업 간의 UObject 레퍼런스를 추적합니다. 즉, 가비지 컬렉션이 진행되는 동안 TObjectPtr 노출 UPROPERTY에 할당하면 즉시 해당 오브젝트가 도달 가능한 것으로 표시됩니다. 이는 가비지 컬렉터 쓰기 장벽이라고도 합니다.
엔진은 이미 UObject 또는 FGCObject, AddReferencedObjects 함수 등의 가비지 컬렉터에 UObject를 노출하는 모든 위치에서 원시 C++ 포인터 대신 TObjectPtr을 사용하도록 변환되었습니다. 언리얼 엔진으로 빌드한 프로젝트에서 점진적 도달 가능성 분석을 사용하려면 모든 원시 C++ 대신 TObjectPtr을 사용하도록 UPROPERTY 인스턴스를 변환해야 합니다. 그렇지 않으면 가비지 컬렉션이 일부 UObject 메모리를 너무 일찍 회수할 수 있습니다. 이 기능은 초기에는 실험단계 기능으로 출시됩니다. 왜냐하면 여전히 도달 가능성 분석 단계가 지정된 시간제한을 초과할 수 있기 때문입니다.
점진적 도달 가능성 분석 활성화
다음 콘솔 변수를 프로젝트의 DefaultEngine.ini 파일에 추가하여 점진적 도달 가능성 분석을 활성화할 수 있습니다.
[ConsoleVariables]
gc.AllowIncrementalReachability=1 ; enables Incremental Reachability Analysis
gc.AllowIncrementalGather=1 ; enables Incremental Gather Unreachable Objects
gc.IncrementalReachabilityTimeLimit=0.002 ; sets the soft time limit to 2ms추가 콘솔 변수
스트레스 테스트 및 디버깅 목적으로 추가 콘솔 변수 세트도 사용할 수 있습니다.
| 콘솔 변수 | 설명 | 유형(Type) |
|---|---|---|
| 지정된 프레임 수만큼 도달 가능성 분석을 딜레이합니다. GC 장벽의 스트레스 테스트에 사용됩니다. |
|
| 도달 가능성 분석이 완료된 후 테스트를 실행하여 도달할 수 있는(유효한) 오브젝트가 도달할 수 없는(곧 소멸될) 오브젝트를 참조하지 않는지 확인합니다. | 0: 비활성화, 1: 활성화 |
| 이전 가비지 컬렉션이 완료된 뒤 점진적 가비지 컬렉션을 계속 재시작합니다. | 0: 비활성화, 1: 활성화 |
퍼포먼스 비교
다음은 점진적 도달 가능성을 비활성화한 상태에서 샘플 프로젝트의 퍼포먼스 그래프를 언리얼 인사이트에서 시각화한 것입니다. 파란색 선은 총 프레임 시간을, 주황색 선은 도달 가능성 분석에 소요된 시간을 나타냅니다. 언리얼 인사이트는 여러 프레임으로 구분된 단일 이벤트 사이에 연속 그래프 선을 표시하므로 전체 타임라인에 걸쳐 가비지 컬렉션이 실행되는 것처럼 보일 수 있지만, 실제로는 한 번에 한 프레임에 대해서만 실행됩니다.
다음 그래프 비교의 첫 번째 이미지에서는 가비지 컬렉션이 실행될 때마다 급증 현상이 나타납니다(타임라인 상단에 GC 라벨로 표시됨).
점진적 도달 가능성이 활성화된 두 번째 이미지에서는 점진적 도달 가능성을 켜면 GC 지연 급증이 사라지고 이제 점진적 도달 가능성이 여러 프레임에 걸쳐 분할된 것을 볼 수 있습니다(이제 더 넓은 연두색 막대로 표시됨).
알려진 제한 사항
증분 도달 가능성은 완전히 스레드 세이프하지 않습니다. 특정 상황에서는 가비지 컬렉터가 UObject 그래프를 스캔하는 동안 작업자 스레드에서 조작 중인 오브젝트가 도달 가능한 것으로 표시되지 않을 수 있습니다. 이로 인해 오브젝트가 조기에 가비지 컬렉션될 수 있습니다. 단일 스레드 빌드(예: 전용 서버)에서만 점진적 도달 가능성을 활성화하는 것이 좋습니다.