명시적해제(free, delete 등)의 프로그래밍 오류 가능성
- 자신에 대한 참조가 존재함에도 불구하고, 이른 시점에 해제될 수 있음
- 더 이상 사용하지 않는 객체를 해제하지 않음
- 둘 이상의 서브 루틴이 한 객체에 대한 참조를 공유하는 경우 흔히 발생
- 프로그래밍의 내재적인 문제에 기인
- 객체의 생명성은 전역적 속성인데 반해, 명시적해제는 지역적 속성이기 때문에 객체의 안전한 해제는 복잡한 문제
- 이 문제를 해결하기 위한 노력
- 객체의 소유권을 관리함에 있어 일관성이 있어야 함
- 가능한 힙할당을 하지 말것 (스택 메모리 사용)
- 참조를 전달하기 보다는 인자와 결과의 전체 내용을 복사하는 방식
- 메모리 압박이 심해지고 객체 공유가 안됨
- 메모리 풀링(pooling)
자동 동적 메모리 관리
- 위의 문제를 해결하기 위해 나온 기법
- 댕글링 포인터는 발생하지 않음
- 메모리 누수는 보장 못함
- 접근 가능하며 제약이 없이 계속 커지는 자료구조
- 접근은 가능 하지만, 결코 사용되지 않는 자료구조
- 좀 더 본질적인 부분
- 보통 고도의 응집성과 낮은 결합성의 컴포넌트를 만드는 것이 이상적인데, 올바른 메모리 관리 관점으로 보면 모듈은 다른 모듈의 메모리 관리 규칙을 알 필요가 없어야 함. 이와는 반대로 명시적 메모리 관리는 컴포넌트 간의 통신을 최소화해야 하는 소프트웨어공학의 원칙과는 역행
- 그래서 가비지 컬렉션의 핵심은 코드를 단순화할 수 있다는 것 보다는 인터페이스와 메모리 관리문제를 분리시켜 준다는 것
- 제대로 된 가비지 콜렉션 기법이라면 가져야 할 특징
- 안정성
- 사용 중인 객체의 저장 공간을 회수하면 안됨.
- 처리량
- 가비지 수집에 소비된 전체시간은 가능한 적어야 함
- 완전성
- 정지시간
- 프로그램 실행 중에 가비지 컬렉터가 끼어드는 시간을 최소화 하는 것
- 공간 오버헤드
- 객체별 메모리 관리용 공간(Reference Count 등)을 저장하기 위한 비용
- 특정 언어의 최적화
- 함수형, 선언, 논리 언어 등 각 언어별로 메모리가 사용 되는 형태가 다르기 때문에 다양한 기법으로 구현 가능하다.
- 확장성과 이식성
- 다양한 병렬 하드웨어 또는 운영체제 간에 호환 되어야 한다.
- 위 특징 모두를 갖춘 가비지 콜렉션 기법은 없음 trade-off 필요
- 어떤 기법들이 어디에 집중 하는지 앞으로 알아가면 된다.
성능의 불이익
- 명시적 관리와 자동 관리 사이에 간단한 비교는 힘듦
- 불이익은 있지만 통상적으로 생각하는 만큼은 아님 malloc과 free 같은 명시적 연산 또한 상당한 비용을 초래
뮤테이터와 컬렉터
- 뮤테이터
- 객체의 할당과 참조에 따른 그래프를 변형시키는 역할
- 컬렉터
- 접근할 수 없는 객체를 찾아 이들의 저장 공간을 회수하는 역할