프로그래밍 언어/C#

Garbage Collection(가비지 컬렉션)

gcreators 2024. 9. 4. 16:37

C#의 데이터 타입에는 크게 두가지가 있다

 

Value Type : int float 같은 타입
Reference(참조) Type : 모든 클래스는 참조 타입 -> class는 복사를 하면 얕은 복사가 된다.
참조는 0바이트 : 해당 주소를 부르는 이름이 변수인데 포인터는 이 주소를 저장하는 곳이라 8바이트의 크기를 가지지만, 참조는 해당 주소를 부르는 이름(변수)가 하나가 더 추가 되는 개념이다.

 

이를 기억해두고 있어야 한다.

 

C#은

C나 C++과 다르게 동적할당 된 데이터를 개발자가 임의로 메모리 해제를 하는 것이 불가능하다.

대신 이를 해결해주기위해 나온 것이 바로 가비지 컬렉션(Garbage Collection)이다.

 

가비지 컬렉션은 자동으로 메모리를 관리해주는 편리한 기능을 가지고 있다.

따라서 개발자의 생산성이 올라가는 효과를 주게 된 것은 좋으나

 

가비지 컬렉션이 동작되는 구조에 의해 할당된 메모리의 해제가 제때 이루어지지 않는다면

좋지못한 프로그램이 되어버리기에 사용에 주의가 필요하다

 

어떠한 방식으로 작동되는지 지금부터 함께 알아보자

 

가비지 컬렉션은 기본적으로는 메모리가 부족할거 같을때 실행된다

우리가 unity로 만든 게임(주로 모바일)에서 가끔가다 뜬금 없이 끊킬때가 있는데

이때가 메모리가 쌓여 가비지 컬렉션이 돌 때 이다.

 

이런 형태로 메모리에 데이터가 쌓였다고 치자

이중에 이미 다 활용이 되어 필요가 없는 데이터가 있을 것 이다.

그럼 해당 데이터를 지우고 메모리에 여유 공간을 다시 만들게 되는데

이런식으로 메모리 공간을 비우게 된다

이 이후가 문제인데

가비지 컬렉션이 나갈때마다 전체 메모리를 검사하게 된다면 생산성이 매우 나빠지게 될 것이다

이를 해결하기 위해

가비지 컬렉션은 다음에 자기가 나왔을때도 살아 있을거 같은 데이터들의 세대(generation)를 올려주게 된다(1->2)

 

그리고 다시 용량이 필요해 질 것 같아서 가비지 컬렉션이 나왔을 때 1세대부터 우선 검사를 하는 것이다.(세대가 낮다는 것은 금방 만들어진 데이터 라는 것임)

 

그런데.... 이렇게 세대를 올리다 보면

이런식으로 메모리가 모두 높은 세대로 차게 되는 경우가 나오지 않겠는가? 이때 모든 세대를 돌면서 메모리 정리를 하기 때문에 게임을 켜두다가 갑자기 뜬금 없는 렉이 걸리는 것 이다.

 

이런 가비지 컬렉션의 특징으로 인해 C#으로 게임을 만들게 되면 메모리를 관리하는 것이 힘들다

(그리고 unity는 C#을 활용한다.)

 

또한 가비지 컬렉션은 용량이 큰 데이터가 한번에 동적할당이 된다면

중요한 데이터 라고 생각하고 최고세대로 바로 등업을 시켜버리는 경우도 있다.

이런 큰 용량의 데이터가 계속 활용된다면 큰 문제는 없겠지만

잠깐 활용하고 말 것 이라면 문제가 생기지 않겠는가?

 

이러니 이를 유의하고 개발을 진행할 수 있어야 한다.