[CS] Garbage collection / 가비지 컬렉션

Onam Kwon·2022년 7월 18일
0

CS

목록 보기
3/22
post-custom-banner

Garbage collection / 가비지 컬렉션

  • 메모리 관리 방법중 한 가지.
  • 동적 할당된 데이터중, 사용되지 않는 데이터를 자동으로 삭제하는 기능.
  • 메모리가 부족할 경우 가비지 컬렉터(GC)가 작동해 더이상 필요하지 않은 메모리들을 해제한다.
  • John McCarthy라는 사람이 1959년에 메모리 관리를 위해 만들었다.

Java

  • Java에서는 GC가 기본적으로 자동으로 작동.
  • Java를 처음 접했을때 메모리 할당 해제가 없어서 궁금했었는데 자동으로 날려준다함.

C++

  • C++는 자바와 다르게 메모리를 기본적으로 해제해주는 기능이 없다. 따라서 수동으로 메모리 관리를 잘 해줘야 한다.
    • 다른 방법으로는 가능하다고 함.

Tracing GC

  • 추적 기반 가비지 컬렉션.
  • 가장 널리 알려진 기법.
  • 프로그램 실행중, 특정한 시간에 할당되어있는 모든 메모리를 조사하는데 그것이 현재 접근 가능한지 여부를 파악하며 접근이 불가능하다면 쓰레기 메모리로 간주하여 해제하는 방식.
  • root: 항상 접근 가능한 메모리.
    • 루트에서부터 검사를 시작해 메모리가 참조하는 모든 메모리들을 확인 및 반복.
  • 위 방법은 중간에 메모리 변경시 재확인을 해야하므로 프로그램이 전체적으로 정지된다. 때문에 이 방식을 채택하면 실행도중 잠깐의 멈춤이 발생한다.

Incremental GC

  • 점진적 가비지 컬렉션.
  • 마킹과 해제를 한번에 하지 않고 여러 번에 걸쳐서 수행하는 방식.
    • mark: 해제 가능한 메모리인지 식별 하기 위한 표식.
  • 마킹이 끝난 후 접근이 불가능하다고 알려진 메모리는 다시 접근 가능해질 수 없다. 따라서 해당 메모리의 할당 해제는 언제 해도 상관 없으므로 여러번에 걸쳐서 수행.
    • 프로그램을 통째로 정지하는 것에 비해 수집및 해제 한 사이클에 걸리는 시간은 더 오래 걸릴 수 있지만, 한번 GC를 수행할 때 프로그램이 정지하는 시간은 줄일 수 있다.

tri-color marking

  • 세가지 색상 white gray black 존재.
    • white: 접근 불가능한 메모리. 메모리 재사용 되어질 후보.
    • gray: 루트에서 참조가능한 메모리이지만 해당 메모리에서 참조하는 메모리를 아직 마킹하지 않은 경우. 루트에서 참조될 수 있으므로 해제 후보가 아니며 스캔된 후 black으로 바뀐다.
    • black: 루트에서 참조되어질 수 있으며 해당 메모리가 참조하는 메모리의 마킹도 끝남. 해제 후보가 아님.
  • 루트부터 조사를 시작하며, 흰색인 메모리를 발견하면 회색으로 마킹.
  • 루트를 모두 마킹했으면 회색으로 마킹된 메모리를 조사하여 해당 메모리가 참조하는 모든 메모리를 회색으로 마킹. (점진적으로 발견시 회색으로 변해감).
  • 윗 단계가 끝나면 회색을 모두 검은색으로 바꿈. 완료시, 남은 메모리는 모두 흰색이거나 검은색이며 접근 가능여부가 정해짐.
    • 위의 방법으로 GC가 중단되어도 다음에 회색부터 이어서 시작한다면 여러번에 걸쳐 GC가능.

Generational GC

  • 위의 방법들이 사용되다가 객체에 메모리를 할당후 쓰레기 메모리가 되기까지 걸리는 시간을 추적했을 때 대부분의 객체는 잠깐 쓰다가 버려지며, 반대로 오래 살아서 쓰이는 경우는 비교적 적다는 추세를 인지.
  • 위 사실에 따라서, 잠깐 쓰고 사라질거같은 객체를 상대적으로 크기가 작은 New 영역에 할당하고, New 영역에서 일정시간 이상 살아남은 객체가 있다면 Old 영역으로 이동시켜 세대를 구분하는 방법도 사용되고 있다.
    • 대부분의 쓰레기 메모리는 New 영역에서 발생하므로, 상대적으로 작은 영역만 추적하면 효율적으로 메모리 관리가 가능.

Reference counting based GC

  • 한 메모리가 다른 메모리를 얼마나 자주 참조하는지 횟수를 세어 접근 가능과 불가능을 나누는 방식.
    • 이 방식은 한 메모리에서 다른 메모리를 참조하면 그 다른 메모리의 참조 횟수에 1을 더하고 참조를 중단하면 참조 횟수에 1을 뺌.
    • 만약 1을 뺀 후 참조 횟수가 0이라면 해당 메모리에 접근을 아무도 못하고 있는 것이므로 해당 메모리를 해제.
  • 추적 기반 GC의 경우 실제 접근이 불가능해지는 시점과 그 사실을 인식하는데까지 걸리는 시간이 어느정도 떨어져 있는데, 참조 횟수 카운팅 방식에서는 접근이 불가능해지자마자 바로 소멸에 들어감.
    • C++ Python 같은 소멸자를 구현할 수 있는 언어에서 종종 채택됨.
  • 이 방식을 구현할 경우 두가지 단점이 존재한다.
    • 대입문마다 참조 횟수를 변경하도록 작성해야 하는데, 이 부분이 프로그램을 느리게 만든다. 횟수를 올리는 부분보다 횟수를 내리는 부분에서 조건문, 함수 호출 등이 실행되므로 대입이 자주 일어나는 곳에서는 비효율적일 수 있다.
    • 순환 참조(Cyclic reference). 두개의 객체가 서로를 참조하고 있고 그 두개의 객체는 외부로부터 참조가 되지 않고 있다면, 이 두개의 객체는 참조 횟수가 둘다 0이 아니라서 해제할 ㅓ수가 없으며 메모리 누수로 이어짐.
profile
권오남 / Onam Kwon
post-custom-banner

0개의 댓글