2023년 3월 10일 금요일

가비지 콜렉션(Garbage Collection - GC)

탄생배경

가비지 콜렉션(Garbage Collection - GC)은 메모리 관리 기법 중 하나로, 프로그램에서 더 이상 사용하지 않는 동적 할당 메모리를 자동으로 탐지하고 해제하는 기능이다. 이러한 기능은 프로그래머가 직접 메모리 관리를 수행할 필요 없이 프로그램 실행 중 자동으로 처리되므로 개발 생산성과 코드의 안정성을 높이는 데 큰 역할을 한다.

GC가 등장하게 된 배경은 프로그래밍 언어의 발전과 함께 이루어졌다. 초기의 어셈블리어, 포트란, C 언어와 같은 저수준 언어에서는 메모리 관리를 프로그래머가 수동으로 처리해야 했다. 이 때문에 메모리 누수(memory leak)나 해제되지 않은 메모리 등의 문제가 발생하기 쉬웠다. 이러한 문제는 시스템의 안정성과 신뢰성을 저해하며, 유지 보수 비용과 작업량을 증가시켰다.

이에 대한 대안으로 GC가 등장하게 되었다. GC는 프로그래머가 메모리 관리에 대한 부담을 덜어주면서도 안정성과 신뢰성을 높일 수 있는 메모리 관리 기법으로 인기를 끌게 되었다. 특히, 객체지향 프로그래밍 언어의 대표격인 자바(Java)에서는 GC가 필수적으로 적용되어 있으며, 이를 통해 자바 개발자들은 메모리 관리에 대한 부담을 줄이고 안정적인 코드를 작성할 수 있게 되었다.

GC는 초기 개발 비용은 높지만, 코드 안정성과 유지보수 비용 감소 등의 장점으로 인해 현재 대부분의 프로그래밍 언어에서 적용되는 중요한 메모리 관리 기법 중 하나이다.

가비지 콜렉션 기법의 종류

참조 카운팅(Reference Counting)
  • 객체가 참조를 유지하는 변수나 객체의 수를 세는 방법
  • 참조 수가 0이 되면 메모리를 해제
  • 순환 참조(circular reference) 문제가 발생하여 추가적인 기법 필요
마크 앤 스위프트(Mark and Sweep)
  • 도달 가능한(reachable) 객체를 찾기 위해 마크 작업 수행
  • 도달 불가능한(unreachable) 객체를 해제하기 위해 스위프트 작업 수행
  • 모든 객체를 검사하므로 처리 시간이 오래 걸릴 수 있음
살아 있는 객체(Alive Object) 목록
  • 모든 객체를 검사하지 않고, 메모리에서 살아 있는 객체만을 추적하여 관리
  • 메모리 공간이 커져도 처리 시간이 일정함
  • 살아 있는 객체를 추적하기 위한 추가적인 데이터 구조 필요
세대 기반(Generational)
  • 객체의 수명이 짧은 경우가 많다는 가정에서 출발
  • 새로 생성된 객체는 1세대(Generation 1)로 분류하고, 오래된 객체일수록 2세대(Generation 2) 이상으로 분류하여 각 세대별로 GC 수행
  • 처리 시간이 크게 개선될 수 있음
병행(Concurrent)
  • GC 수행 중에도 어플리케이션이 실행될 수 있도록 함
  • GC와 어플리케이션 간에 경쟁 조건(race condition)이 발생할 수 있어 추가적인 동기화 작업 필요
카드마킹(Carding)
  • 대용량 메모리 관리에 효과적인 방법
  • 메모리 영역을 카드(card)로 구분하고, 변경이 발생한 카드만 검사하여 GC 수행
  • 처리 시간을 대폭 개선할 수 있음