가비지컬렉션이란?

Seungmin Shin·2022년 2월 16일

쓸모없는 메모리를 정리하다.

우리가 코딩을할때 변수, 함수, 객체들을 사용하며 작업환경 어딘가에 있을 보이지 않는 메모리를 차지하게 된다.
메모리 용량은 한정되어 있고, 메모리가 쌓이다가 전부 차게 되면 그대로 컴퓨터가 뻗어버리게 된다.

그래서 우리는 코드를 짜고 메모리에 할당을 하다가 더 이상 사용하지 않는 메모리를 찾아 지우고 사용 가능한
메모리로 만들기 위한 작업을 해야했다.

C나 C++ 에서는 이러한 메모리관리를 하는 코드를 직접짜야됬다고 하는데,
자바를 비롯한 새로운 언어에서는 가비지컬렉션 이라는것을 도입하여 코드를 일일이 짜야했던 개발자 대신에
자동으로 메모리를 관리해주는 가비지컬렉터를 사용하기 시작한다.

그렇다면 이 가비지컬렉터는 어떤식으로 동작하는 것일까.

가비지컬렉터?

일단 가비지컬렉터는 세가지 일을 한다.

  1. 메모리 할당
  2. 사용중인 메모리 인식
  3. 사용하지 않는 메모리 인식

가비지 컬렉터가 하는일은 메모리가 부족할때 더이상 사용하지 않는 메모리 즉, 가비지(쓰레기) 를 정리해주는
역할을 하는것이다. 이름을 보면 어느정도 예상이 가능 할것이다.

일단 메모리에 대해 알고 넘어가자. 프로그램을 실행할때 메모리를 관리하는 OS 에 프로그램 실행에 필요한
메모리를 요청하게 된다. 이때 메모리를 어디에 저장할지 그 주소를 할당하게 되는데 이 주소를 Offset 주소
라고 한다.

이렇게 할당된 메모리중에는 프로그램이 돌아가면서 무조건적으로 가비지로 변환되는것들이 있다. 기존에 있던
메모리들이 새롭게 재선언 되거나 형변환이 된다면 기존의 주소를 잃어버려 찾을 수 없게 되므로 사용되지
못하고 떠도는 메모리가 되는것이다. 이때 가비지컬렉터가 해당 메모리를 찾아 다시 사용가능한 메모리가
될 수 있게 메모리해제를 시키는것이다. 이것이 가비지컬렉터가 하는 일이다.

어떻게 일하는가?

그렇다면 가비지컬렉터는 어떤식으로 메모리를 정리하는걸까? 두가지의 방법을 사용한다고 한다.
뭐 더 딥하게 들어가면 어렵다고 하는데.. 일단은 이정만 개념적으로 알아두면 좋을 듯 하다.

  1. Reference Counting
    Reference Counting 은 이름 그대로 "참조" 를 이용한다. 객체가 참조될때마다 카운트를 주게 되고.
    객체의 사용이 끝나거나 객체를 반환하게 되면 카운트가 하나 감소하게 된다. 이렇게 최종적으로 카운트가
    0이 된다면 해당 객체는 메모리에서 소멸되는것이다.

  2. Mark & Sweep
    가비지 컬렉터에는 GC Root 라는것이 있다. 이 루트들은 힙 외부에서 접근할 수 있는 변수나 오브젝트를
    뜻한다. GC Root 는 말 그대로 가비지 컬렉션의 루트 라는 뜻이다. 이 GC Root 에서 시작해서 모든
    오브젝트를 탐색하며 참조하게 된다. 그리고 참조가 된다면 해당 오브젝트를 Mark 한다. 그러다가 객체와
    루트의 연결이 끊기게 되면 이제 연결이 되지 않는 오브젝트를 mark를 하지 못하니 해당 오브젝트를
    삭제하는 것이다.

비교?

일단 레퍼런스 카운팅은 참조를 기반으로 판별을 하는데 그러다 보니 순환참조의 상황이 발생한다면
서로가 서로를 참조하기에 카운트가 0이 되지 못하면서 삭제되지 않는다. 이러한 문제를 해결한것이
마크 앤 스윕인데. 이것은 서로가 참조를 하고 있더라도 GC Root 에 Mark 되지 않는다면 삭제 될 수 있다.
그렇다고 Mark & Sweep 만 쓰면 되는것 아니냐고 생각하겠지만 막상 그렇지도 않은것같다.

Reference Counting 은 카운트를 세기만 하면 되기때문에 작업에 큰 부담은 없다. 아까같은 순환참조
문제만 빼면 크게 어려울것이 없지만, Mark & Sweep 방식은 한번 탐색을 시작하면 노드 전체를 순환해야
하기 때문에 코드가 조금만 복잡해져도 가벼운작업이 아니게 된다. 이런것을 잘 파악하면 좋을 듯 하다.

profile
Frontend Developer

0개의 댓글