2016년 7월 19일 화요일

가비지 콜렉션 (Garbage Collection)의 탄생 배경

명시적해제(free, delete 등)의 프로그래밍 오류 가능성
  • 자신에 대한 참조가 존재함에도 불구하고, 이른 시점에 해제될 수 있음
    • 댕글링 포인터
  • 더 이상 사용하지 않는 객체를 해제하지 않음
    • 메모리 누수
  • 둘 이상의 서브 루틴이 한 객체에 대한 참조를 공유하는 경우 흔히 발생
    • 멀티쓰레드 프로그래밍에서는 더욱 심함
  • 프로그래밍의 내재적인 문제에 기인
    • 객체의 생명성은 전역적 속성인데 반해, 명시적해제는 지역적 속성이기 때문에 객체의 안전한 해제는 복잡한 문제
  • 이 문제를 해결하기 위한 노력
    • 객체의 소유권을 관리함에 있어 일관성이 있어야 함
      • 가능한 힙할당을 하지 말것 (스택 메모리 사용)
      • 참조를 전달하기 보다는 인자와 결과의 전체 내용을 복사하는 방식
      • 메모리 압박이 심해지고 객체 공유가 안됨
      • 메모리 풀링(pooling)

자동 동적 메모리 관리

  • 위의 문제를 해결하기 위해 나온 기법
    • 댕글링 포인터는 발생하지 않음
    • 메모리 누수는 보장 못함
      • 접근 가능하며 제약이 없이 계속 커지는 자료구조
      • 접근은 가능 하지만, 결코 사용되지 않는 자료구조
  • 좀 더 본질적인 부분
    • 보통 고도의 응집성과 낮은 결합성의 컴포넌트를 만드는 것이 이상적인데, 올바른 메모리 관리 관점으로 보면 모듈은 다른 모듈의 메모리 관리 규칙을 알 필요가 없어야 함. 이와는 반대로 명시적 메모리 관리는 컴포넌트 간의 통신을 최소화해야 하는 소프트웨어공학의 원칙과는 역행
    • 그래서 가비지 컬렉션의 핵심은 코드를 단순화할 수 있다는 것 보다는 인터페이스와 메모리 관리문제를 분리시켜 준다는 것
  • 제대로 된 가비지 콜렉션 기법이라면 가져야 할 특징
    • 안정성
      • 사용 중인 객체의 저장 공간을 회수하면 안됨.
    • 처리량
      • 가비지 수집에 소비된 전체시간은 가능한 적어야 함
    • 완전성
      • 힙 내의 모든 가비지를 회수해야 한다.
    • 정지시간
      • 프로그램 실행 중에 가비지 컬렉터가 끼어드는 시간을 최소화 하는 것
    • 공간 오버헤드
      • 객체별 메모리 관리용 공간(Reference Count 등)을 저장하기 위한 비용
    • 특정 언어의 최적화
      • 함수형, 선언, 논리 언어 등 각 언어별로 메모리가 사용 되는 형태가 다르기 때문에 다양한 기법으로 구현 가능하다.
    • 확장성과 이식성
      • 다양한 병렬 하드웨어 또는 운영체제 간에 호환 되어야 한다.
    • 위 특징 모두를 갖춘 가비지 콜렉션 기법은 없음 trade-off 필요
    • 어떤 기법들이 어디에 집중 하는지 앞으로 알아가면 된다.

성능의 불이익

  • 명시적 관리와 자동 관리 사이에 간단한 비교는 힘듦
  • 불이익은 있지만 통상적으로 생각하는 만큼은 아님 malloc과 free 같은 명시적 연산 또한 상당한 비용을 초래

뮤테이터와 컬렉터

  • 뮤테이터
    • 객체의 할당과 참조에 따른 그래프를 변형시키는 역할
  • 컬렉터
    • 접근할 수 없는 객체를 찾아 이들의 저장 공간을 회수하는 역할