[C#] 세대별 가비지 컬렉션 알고리즘


얼마 전 포스팅에서 가비지 컬렉션의 동작원리에 대해 알아보았습니다.

그렇다면 오늘은 가비지 컬렉션의 성능을 높이기 위한

세대별 가비지 컬렉션 알고리즘에 대해 알아보도록 하겠습니다.


가비지 컬렉션에 대해 공부를 하는 이유는 유니티에서 게임오브젝트를

동적 생성/삭제 하는 과정에서 가비지 컬렉터의 활동 빈도를 높이게 된다고 합니다. 


가비지 컬렉터의 비용은 공짜가 아니기 때문에 이 또한 신중하게 관리되어야 할 메모리입니다.

때문에 메모리 풀을 이용하여 필요한 오브젝트를 미리 생성해놓고 사용하게 되는데

이 또한 가비지 컬렉터의 원리를 제대로 이해해야만 최대 효율로 이용할 수 있겠다는 생각이 들어서 입니다.


세대별 가비지 컬렉션 알고리즘

들어가기전에 이 알고리즘의 핵심만 간단하게 짚어보자면

오래 살아남을 것 같은 객체를 모아놓고 비교적 관심을 덜 주자는 것입니다.

그렇게 된다면 모든 객체에 관심을 주는 것보다 효율적인 관리방식이 될 수 있겠지요.


그렇다면 객체의 수명을 어떻게 예측해야 할까요?


01.   새로 할당된 객체들 모두 0세대에 포함됩니다.

0세대가 임계치에 도달하게되면 가비지 컬렉터는 0세대에 대해 가비지 컬렉션을 수행하게 됩니다.


02.   가비지 컬렉션 수행 후 살아남은 객체들을 1세대로 옮겨지게 됩니다.


03.   이후 또다른 객체가 할당되어 들어온다면 그 객체들은 당연히 0세대에 포함됩니다.

0세대가 또 다시 임계치에 도달하게 되면 가비지 컬렉터는 0세대에 대해 가비지 컬렉션을 수행합니다.


04.   이번에는 1세대가 임계치에 도달하게 되었습니다.

마찬가지로 가비지 컬렉션을 수행합니다.


05.   1세대의 가비지 컬렉션에서 살아남은 객체는 2세대로 옮겨지게 됩니다.

객체의 수명은 이런식으로 가비지 컬렉터에서 오래 살아남았다는 기준으로 정해지게 됩니다.


06.   이러한 방식으로 0세대, 1세대, 2세대를 구분하여 각각의 임계치에 도달하면 해당 세대에 대해 가비지 컬렉션을 수행하게 됩니다.


-->  0세대가 포화된다면 오로지 0세대만 가비지 컬렉션을 수행 한 후 1세대로 이동

1세대가 포화된다면 0세대와 1세대만 가비지 컬렉션을 수행 한 수 각각 1세대, 2세대로 이동


2세대 또한 똑같은 메커니즘으로 가비지 컬렉션을 수행할까요?


-->  2세대가 포화되게 된다면 더 이상 다른 곳으로 옮겨지지 않기 때문에, 전체 가비지 컬렉션을 수행하게 됩니다.


위의 세대별 가비지 컬렉션 알고리즘으로 인해 생성과 삭제가 빈번한 객체에 대해서만

가비지 컬렉터가 신경을 쓸 수있게 하는 메커니즘이 완성되었습니다.


하지만 2세대가 포화되게 된다면 전체 가비지 컬렉션이 수행된다는 항목에 주의를 기울여야 합니다.

전체 가비지 컬렉션이 수행되면 CLR은 앱의 실행을 잠시 멈추고 전체 가비지 컬렉션을 수행함으로써

여유 메모리를 확보하려 듭니다. 앱이 차지하고 있던 메모리가 크면 클수록 전체 가비지 컬렉션의

시간이 길어지므로 앱이 정지하는 시간도 그만큼 늘어나겠지요.

이것이 바로 우리가 가비지 컬렉션을 이해해야하는 중요한 이유입니다.




+ Recent posts