간단히 말해서 : 가비지 콜렉터는 재귀를 사용하지 않습니다. 그들은 본질적으로 두 세트를 결합하여 추적을 제어합니다 (결합 할 수 있음). 추적 및 셀 처리 순서는 관련이 없으므로 세트를 표현할 수있는 상당한 구현 자유를 제공합니다. 따라서 실제로 메모리 사용량이 매우 저렴한 많은 솔루션이 있습니다. 힙에 메모리가 부족할 때 GC가 정확하게 호출되므로 이는 필수입니다. 새로운 페이지를 쉽게 할당 할 수 있고, 적은 공간이 아니라 데이터 위치가 부족하기 때문에 가상 메모리가 큰 경우 상황이 약간 다릅니다
.
귀하의 질문이 적용되지 않는 참조 계산이 아닌 가비지 수집기 추적 을 고려하고 있다고 가정합니다 .
문제는 아직 추적되지 않은 포인터를 포함하는 액세스 가능한 메모리 셀의 세트 (추적되지 않은) 세트 를 추적 하기 위해 추적하는 메모리 비용에 초점을 맞추고 있습니다.유이것은
가비지 수집에 대한 메모리 문제의 절반에 불과합니다 . GC는 또한 프로세스의 끝에서 다른 모든 셀을 회수하기 위해 액세스 가능한 것으로 밝혀진 모든 셀 의 세트 (방문 용) 의 다른 세트를 추적해야합니다 . 서로를 논의하는 것은 비용이 비슷하고 비슷한 솔루션을 사용하며 심지어 결합 될 수 있기 때문에 제한이 있습니다.V
첫 번째로 주목해야 할 것은 모든 추적 GC가 프로그램에서 액세스 가능한 메모리의 셀 방향 그래프의 체계적 탐색을 기반으로 동일한 추상적 모델을 따르는 것입니다. 이를 위해 다음 세트를 사용합니다.
뮤 테이터에 의해 이미 액세스 가능한 것으로 밝혀진 셀 의 세트 (방문) , 즉 GC가 수행되는 프로그램 또는 알고리즘. 세트 V 는 두 개의 분리 된 서브 세트로 분할된다 :
V = U ∪ T ;VVV= U∪ T
아직 추적되지 않은 포인터를 가진 방문한 셀 의 세트 (추적되지 않음);유
모든 포인터가 추적 된 방문 셀의 세트 (추적)티
우리는 또한 H 참고H 힙에있는 모든 세포의 집합 여부를 사용한다.
만 와 U , 또는 U 와V유유 , 필요성 작업에 알고리즘 어떻게 든 표현한다.티
이 알고리즘은 런타임 시스템에 알려진 일부 루트 포인터 (일반적으로 스택 할당 메모리의 포인터)에서 시작하여 추적되지 않은 집합 에있는 모든 셀을 넣습니다 (따라서유 도 있음)습니다.V
그런 다음 수집기는 셀을 하나씩 가져와 각 셀 c의 모든 포인터를 확인합니다. 각 포인터에 대해 뾰족한 셀이 V에 있으면 아무 것도 수행되지 않습니다. 그렇지 않으면 뾰족한 셀이 포인터를 아직 확인하지 않았으므로 U에 추가됩니다 . 모든 포인터가 처리되면 셀 c 는 추적되지 않은 집합 U 에서 추적 집합으로 전송됩니다.유기음V유기음유 됩니다.티
가 비어 있으면 추적이 종료됩니다 . 어떤 셀도 U를 두 번 이상 통과하지 않기 때문에 이것은 일어날 수밖에 없습니다 . 그 점에서 V = T , 그리고 모든 셀 V 따라서, 프로그램에 액세스 할 수 알고있는 교정되지 않습니다. 보체 H - V 의유유V= TVH− V 힙 셀이 테이터 프로그램에 의해 연결할 수있는 상기 테이터에 장래 할당을 위해 집에서 회수 될 수 있는지를 판정한다.V
couse 중에서 세부 사항은 세트가 구현되는 방식과 및 U 또는 U 및 여부에 따라 다릅니다.V유유되는 방식과 효과적으로 표현되는 T.티
또한 셀이 무엇인지, 하나의 크기에 관계없이, 셀에 포인터를 찾는 방법, 압축 방법, 가비지 수집에 관한 서적 및 설문 조사에서 찾을 수있는 기타 기술적 인 문제에 대한 세부 정보는 생략합니다. .
이것이 매우 간단한 알고리즘임을 알 수 있습니다. 재귀는 없지만 세트 의 요소에는 루프 가유 끝날 때까지 처리 될 때까지 커질 수 있는 루프 만 있습니다 .여분의 메모리에 대한 선험적 인 가정은 없습니다.
세트를 식별하고 필요한 작업을 저렴하게 수행 할 수있는 모든 것. 셀이 처리되는 순서는 관련이 없으며 (푸시 다운 스택이 필요 없음), 세트를 효율적으로 나타내는 수단을 선택할 수있는 많은 자유가 있습니다.
알려진 구현이 다른 경우 이러한 세트가 실제로 표현되는 방식이 다릅니다. 실제로 많은 기술이 사용되었습니다 :
비트 맵 : 각 메모리 셀에 대해 하나의 비트가있는 맵에 대해 일부 메모리 공간이 유지되며 셀의 주소를 사용하여 찾을 수 있습니다. 해당 셀이 맵에 의해 정의 된 세트에있을 때 비트가 켜집니다. 비트 맵 만 사용하는 경우 셀당 2 비트 만 필요합니다.
또는 각 셀에 특수 태그 비트 (또는 2)를 표시 할 공간이있을 수 있습니다.
로그2피피 셀당 포인터의 개수를, 이는 상기 비트 스택에 의해 감소된다.
셀의 내용 및 해당 포인터에 대한 술어를 테스트 할 수 있습니다.
표시된 세트에 속하는 모든 셀을위한 메모리의 여유 부분에 셀을 재배치 할 수 있습니다.
V티티유
단일 세트에 대해서도 이러한 기술을 실제로 결합 할 수 있습니다.
말했듯이, 위의 모든 것은 일부 구현 된 가비지 수집기에 의해 사용되었습니다. 그것은 모두 구현의 다양한 제약에 달려 있습니다. 또한 메모리 사용량이 다소 저렴할 수 있으며, 최종 결과에 중요하지 않기 때문에 해당 목적에 따라 자유롭게 선택할 수있는 주문 정책 을 처리 함으로써 도움이 될 수 있습니다.
새로운 영역에서 세포를 옮기는 가장 이상한 것처럼 보이는 것이 실제로는 매우 일반적입니다.이를 복제 수집이라고합니다. 가상 메모리와 함께 주로 사용됩니다.
분명히 재귀가 없으며 뮤 테이터 알고리즘 스택을 사용할 필요가 없습니다.
또 다른 중요한 점은 많은 현대 GC가 큰 가상 메모리를 위해 구현 된다는 것 입니다. 그런 다음 새로운 페이지를 쉽게 할당 할 수 있으므로 구현할 공간과 추가 목록 또는 스택을 얻는 것은 문제가되지 않습니다. 그러나 가상 메모리가 크면 공간이 부족하지 않고 지역성이 부족 합니다. 그런 다음 집합을 나타내는 구조와 그 용도 는 데이터 구조 및 GC 실행 의 로컬 성 을 유지하도록 설계되어야합니다 . 문제는 공간이 아니라 시간입니다. 부적절한 구현은 메모리 오버플로보다 수용 할 수없는 속도 저하를 보일 가능성이 높습니다.
나는 충분히 길어 보이기 때문에 이러한 기술의 다양한 조합으로 인해 많은 특정 알고리즘에 대한 언급을하지 않았다.