[ C# ] Garbage Collection

Minsu._.Lighting·2024년 6월 15일
0

📔 [ Modern C++ / C# ]

목록 보기
8/8

💡 Garbage Collection?

  • 사용자가 동적으로 할당한 영역 중 더 이상 사용하지 않는 영역을 찾아 자동으로 해제하는 기능
    - C++의 경우 사용자가 직접 해제해줘야 하지만, C#의 경우 GC가 자동으로 해준다.


💡 Garbage Collection Generation

  • Generation은 객체가 Garbage Collection을 몇번 거쳤는지 나타낸다

  • 세대가 높을 수록 즉, Garbage Collection을 겪고도 생존한 객체들을 중요한 객체로 판단하는 방식

  • 기본적으로 0세대를 대상으로 먼저 Garbage Collection을 시행하고, 그럼에도 공간확보가 부족하다면 1세대까지 포함, 그럼에도 부족하다면 2세대까지 포함시켜 시행한다

📢 2세대까지 포함한 모든 Garbage Collection 수행 시 아예 프로세스를 일시정지하고 우선적으로 수행하기 때문에, 순간적인 프레임 드랍 등이 일어나게 됩니다.



💡 Garbage Collection의 동작 방식

  • 크게 3가지 과정을 거친다.
    1) Mark, 사용되고 있는 개체들을 연결하는 작업
    2) Relocate, 사용되지 않는 개체들을 식별하는 작업
    3) Compact, 필요 없는 객체들을 지우고 살아있는 객체들을 모으는 작업

📌 Mark

Garbage Collection 주기가 시작될 때 일단 모든 object를 가비지로 가정한다.
즉, 루트 목록 내 어떤 루트도 메모리를 가리키고 있지 않다고 가정한다.
이 상태에서 가비지 컬렉터는 루트 목록을 돌면서 각 루트가 참조하는 것들을 마킹한다.
루트가 참조하는 힙 object가 또 다른 힙 object를 참조한다면 이 object 또한 마킹한다.
좀 더 언밀히 말하면 마킹이란 루트 목록에서 시작되는 연결된 그래프를 만드는 것이다.
루트에서 연결될 수 있는 object를 우리는 도달할 수 있는 object라 부른다.

📌 Relocate

루트 목록에서 도달할 수 없는 object들을 가비지로 간주한다.
가비지가 차지한 공간은 비어 있는 공간으로 간주하게 된다.

📌 Compact

루트 목록에 대한 조사가 끝나면 가비지 컬렉터는 힙을 순회하며 가비지가 차지했던 비어있는 공간에 인접한 도달할 수 있는 object들을 메모리 복사를 통해 덮어 씌운다.
도달 가능한 모든 object에 대한 이동이 끝나면 가비지 컬렉터는 포인터의 위치 또한 적절하게 수정한다



💡 Garbage Collection의 중요성

📌 자동으로 방식하는데 왜 동작 방식까지 알아야 하는가..?

  • Garbage Collection도 자원을 사용하는 소프트웨어, 유한한 자원을 사용하는 프로그램에서 Garbage Collection이 사용하는 자원을 줄일 수 있다면 프로그램의 성능이 늘어나기 때문!
    - 이러한 이유를 바탕으로 코드를 작성할 때 아래와 같은 노력들을 할 수 있다.
    • 객체 너무 많이 할당하지 않기
      너무 많은 object를 생성하면 그 만큼 메모리가 금방 차고 Garbage Collection이 빈번히 발생하게 될 것이다.

    • 너무 큰 객체 할당하지 않기

    • 복잡한 참조 관계 만들지 않기
      Garbage Collection 후 도달할 수 있는 object의 세대를 옮기기 위해 메모리 복사를 수행한다. 이때 참조 관계가 복잡하다면 단순히 메모리 복사가 아니라 참조하고 있는 모든 메모리 주소를 수정하는 과정을 거쳐야 한다.

    • 루트를 많이 만들지 않기
      루트 목록을 기반으로 가비지를 찾아내기 때문에 많지 않다면 그만큼 루트 목록을 순회하는 시간을 줄일 수 있다.
profile
오코완~😤😤

0개의 댓글

관련 채용 정보