공부/Unreal Engine 4

가비지 컬렉션 / shared_ptr, weak_ptr

Lero God 2020. 8. 2. 20:58
가비지 컬렉션

 

UE4와 C#에선 가비지 컬렉션에서 메모리를 해제해주는 기능을 제공한다.

C#은 기본으로 제공해 주지만, UE4에선 UObject를 상속 받는 클래스 객체들만 가비지 컬렉팅 대상이 된다.

 

가비지 컬렉션은 일정 주기마다 참조되지 않는 메모리를 검색해서 찾아낸다.

검색은 루트라는 곳에서부터 시작해 참조되는 메모리들은 제외하고, 참조되지 않는 메모리들을 가비지 컬렉팅 한다.

루트에는 전역 변수, 스택, 직접 지정한 루트 객체 등이 있다.

 

가비지 컬렉션은 메모리가 참조가 0이 되는 순간 실행되는 것이 아니고 일정 주기마다 일어나기 때문에

한 번에 많은 양의 메모리를 해제하는 경우가 생긴다.

이 때 프로그램이 버벅이거나 멈추는 일이 생길 수도 있다.

 

 

shared_ptr

 

c++ 표준에는 참조 카운팅 방식의 shared_ptr을, UE4에서도 참조 카운팅 방식의 TSharedPtr을 지원해 준다.

참조 카운팅이란, 객체마다 각자의 참조 카운트를 갖고 있고, 그게 0이 되는 순간 메모리를 자동으로 해제해 주는 방식이다.

 

참조 카운팅을 이용하면 편리하지만, 잘 못 쓰면 메모리 릭 등의 문제가 발생한다.

예를 들면 만약 객체 A와 B가 서로 참조를 하고 있다면, 객체들이 모든 스코프를 벗어나도 서로를 참조하고 있기 때문에, 참조 카운트는 1로 고정되있을 것이다. 그러면 프로그램이 종료되어도 메모리가 해제 안 되는 문제가 발생한다.

이런 문제를 바로 순환 참조(Circular Referencing)라고 한다.

 

 

weak_ptr

 

순환 참조를 해결하기 위한 weak_ptr을 이용하면 해결 할 수 있다.

weak_ptr은 강한 참조가 아닌 약한 참조 카운팅을 올린다.

객체 A는 B를 강한 참조를 하고, B는 A를 약한 참조를 하는 방식으로 순환 참조를 해결할 수 있다.

 

weak_ptr 안에 있는 실제 raw 포인터의 값을 바꾸는 등의 작업을 할려면 shared_ptr로 변환을 한 후에 사용할 수 있다.

weak_ptr을 shared_ptr로 바꾸는 함수는 C++에선 lock을 쓰고, UE4에선 pin을 쓰쟛 :)

 

weak_ptr을 쓰기 적절한 예는 순환 참조 해결, 캐시, 옵저버 패턴 등이 있다.

 

 

 가비지 컬렉션 VS shared_ptr

 

가비지 컬렉션을 이용하면 weak_ptr을 이용해 순환 참조 문제를 해결하는 문제로부터 자유로울 수 있기 때문에

사용하기가 더 쉽다.

하지만 가비지 컬렉션의 동작을 모두 제어할 수 없기 때문에 프로그램이 한 번도 버벅이지 않고

부드럽게 동작해야 하는 경우 쓰기 부적합하다.

 

shared_ptr은 참조가 0이 되는 순간 바로 해제가 되기 때문에 가비지 컬렉션보다 훨씬 속도가 빠르다.

하지만 멀티 쓰레드 환경에서는 raw 포인터보다 느리다는 단점이 있다.

'공부 > Unreal Engine 4' 카테고리의 다른 글

UE4 Delegate  (0) 2020.09.03
UE4 플러그인 모듈 참조  (0) 2020.08.27
UE4 UBT(Unreal Build Tool)  (0) 2020.07.28
UE4 Patch System  (1) 2020.07.26
UE4 Mounting Pak File  (0) 2020.07.22