Garbage Collection이란?

Garbage Collection

  • 메모리 관리 기법 중의 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된 영역을 해제하는 기능
  • 1959년에 리스프의 문제를 해결하기위해 존 메카시가 개발

개요

  • 동적 할당된 메모리 영역 가운데 더 이상 사용할 수 없게 된 영역을 탐지하여 자동으로 해제하는 기법
  • 더 이상 사용할 수 없게 된 영역 : 어떤 변수도 가리키지 않게 된 영역을 의미
  • 자바, C#, 일부 스크립트 언어들은 처음부터 GC를 염두에 두고 설계되어 언어 정의에 GC가 포함되어있지만, C,C++등의 언어는 수동 메모리 관리를 가정하고 설계되어있으나, GC을 지원하는 구현도 존재한다.

장점

  • GC환경에서는 프로그래머가 동적으로 할당한 메모리 영역의 전체를 완벽하게 관리할 필요가 없어진다.
  • 아래 버그들을 줄이거나 완전히 막을 수 있다.
    • 유효하지 않은 포인터 접근 이미 해제된 메모리에 접근하는 버그를 가리킨다. 만약 이 포인터가 해제되고 새로운값이 할당되었다면, 잘못된 값을 읽어오게 된다.
    • 이중 해제 이미 해제된 메모리를 또다시 해제하려는 버그를 말함
    • 메모리 누수 더이상 필요하지 않은 메모리가 해제되지 않고 남아있는 버그. 메모리누수가 반복되면 메모리 고갈로 프로그램이 중단될 수 있다.

단점

  • 어떤 메모리를 해제할지 결정하는 데 비용이 든다 객체가 필요없어지는 시점을 프로그래머가 미리 알고 있는 경우에도 GC알고리즘이 메모리 해제 시점을 추적해야 하므로, 이 작업은 오버헤드가 된다.
  • GC이 일어나는 타이밍이나 점유시간을 미리 예측하기 어렵다. 때문에 프로그램이 예측불가능하게 일시적으로 정지할 수 있다. 이러한 특성은 특히 실시간 시스템에는 적합하지 않다.
  • 할당된 메모리가 해제되는 시점을 알 수 없다. 자원 할당과 변수 초기화를 일치하는 RAII(Resource Acquisition Intialization) 스타일의 프로그래밍에서는, 이것은 자원 해제 시점을 알 수 없다는 것을 의미한다.

방식

1. 포인터 추적 방식

대부분의 GC기법은 포인터 추적 방식을 사용한다.

한 개 이상의 변수가 접근 가능한 메모리는 앞으로 사용할 수 있는 메모리로 간주하고, 그 밖의 메모리를 해제하는 방식을 말한다.

접근 가능한 객체

접근 가능한 객체는 어떤 변수가 직접 가리키는 메모리, 또는 간접적으로 가리키는 메모리를 의미한다. 접근 가능한 메모리는 다음과 같이 재귀적으로 정의할 수 있다.

  1. 변수가 가리키는 객체 여기서 변수는 콜 스택에서 정의된 지역 변수와 전역 변수를 모두 포함한다.
  2. 접근 가능한 객체가 가리키는 모든 객체는 마찬가지로 접근 가능하다.

여러가지 포인터 추적 기법

포인터 추적 기법에는 여러가지 변종이 존재한다.

  1. 표시하고 쓸기(mark and sweep)
    • 표시하고 쓸기 기법은 포인터 추적 기법 가운데 가장 단순한 기법이다
    • 먼저 각 메모리 할당 영역에 표시를 위해 1비트의 메모리를 남겨둔다
    • 표시 단계에서, 모든 변수가 가리키는 영역을 “사용중”이라 표시하고, 그 영역에서 가리키는 또다른 영역 또한 “사용중”으로 표시한다.
    • 모든 메모리 영역을 표시하고 나면, 표시되지 않은 영역을 접근 불가능한 메모리 영역이 된다.
    • 접근 불가능한 메모리 영역들은 쓸기 단계에서 모두 해제한다.
    • 단점 :
      • 표시단계에서 메모리 내용이 변경되지 않아야 하기 때문에 전체 시스템의 실행이 정지된다는 것이다.
      • 전체 메모리 영역을 검사해야 하므로 메모리 페이징을 사용하는 운영체제에서 프로그램의 성능이 저하될 수 있다.
  2. 삼색 표시 기법
    • 표시하고 쓸기 기법의 단점을 보완하기 위해 많은 언어들은 삼색 표시 기법을 사용한다
    • 기본적으로 표시하고 쓸기와 같은 기법이지만, 표시 단계에서 2가지가 아닌 3가지(흰색, 회색, 검은색) 정보 중 하나로 메모리를 표시한다.
    • 다음과 같은 순서로 이루어진다
      1. 각각의 객체를 흰색, 회색, 검은색으로 분류한다.
        • 흰색 : 더이상 접근 불가능한 객체
        • 회색 : 접근은 가능한 객체지만, 이 객체에서 가리키는 객체들은 아직 검사되지 않음
        • 검은색 : 이 영역에서 가리키는 객체들이 흰색 객체를 가리키지 않음
        • 알고리즘이 시작할 대는 변수가 가리키는 객체들이 회색으로 표시되며
        • 그 외의 모든 객체들은 흰색으로 표시된다
      2. 회색으로 표시된 객체 가운데 하나를 선택하여 검은색으로 표시하고, 이 객체가 가리키는 모든 객체들을 회색으로 표시한다.
      3. 회색 객체가 하나도 남지 않을 때가지 위 과정을 반복한다.
      4. 남은 흰색 객체는 접근 불가능한 객체이므로, 모두 해제한다.
    • 삼색 표시 기법은 단순한 표시하고 쓸기 알고리즘과 달리 프로그램이 실행 중에도 병행하여 수행할 수 있다.
    • 또한 메모리가 고갈되었을 때 쓰레기 수집을 실행하는 것이 아니라 주기적으로 수집하는 것이 가능하다.