불행하게도, 그것은 트랩 비트를 가지고 C 표준의 엄격한 읽기 (unsigned char
제외) 모든 종류의 수 있습니다 C.에서 진정으로 플랫폼에 독립적 인 가비지 컬렉터를 만들기 위해 정말 불가능 잘못된 값, 시스템에서 예외 신호 (예 : 정의되지 않은 동작)가 발생합니다. 포인터에 대해 할당 된 블록을 검사 할 때 특정 메모리 블록에 합법적 인 포인터 값이 들어 있는지 여부를 판단 할 방법이 없으며, 값을 보자 마자 바로 잡아낼 수 있습니다.
int로 포인터를 검사해도 도움이되지 않습니다. 포인터와 호환되는 표현을 사용하려면 int 유형이 필요하지 않습니다. intptr_t
은 최신 컴파일러에서만 사용 가능하며 표현도 호환되어야한다고 생각하지 않습니다. int에는 트랩 비트가있을 수 있습니다.
또한 포인터의 정렬 요구 사항을 알지 못합니다. 포인터에 정렬 요구 사항이없는 플랫폼 (즉, 모든 바이트에서 시작할 수 있음)에서는 적절한 바이트 유형 인 memcpy
을 모든 바이트에서 중지하고 결과를 검사해야합니다. 오, 그리고 다른 포인터 유형도 다른 표현을 가질 수 있으며, 또한 피할 수없는 것입니다.
하지만 더 큰 문제는 루트 집합을 찾는 것입니다. Bohem GC와 다른 사람들은 정적 데이터뿐만 아니라 스택을 스캔하여 루트 집합에 들어갈 포인터를 찾습니다. OS의 메모리 레이아웃에 대한 지식 없이는 불가능합니다. 따라서 사용자가 루트 집합의 멤버를 명시 적으로 표시해야 할 필요가 있습니다.이 집합은 가비지 수집기의 포인트를 무효화합니다. 명시 적으로 부여됩니다
이러한 가정을하면 보수적 인 마크 스윕 할당자가 가능해야합니다. 할당이있는 위치에 대한 정보를 보유하고 포인터에 대해 할당 된 블록에서 가능한 모든 정렬 된 포인터 위치를 검사하려면 이진 트리를 사용하십시오. 그러나 명시 적으로 루트 집합을 제공해야 할 필요가 없으므로이 모든 것을 무의미하게 만들 것입니다. 특정 정의되지 않은 개체 집합을 건너 뛸 수 있다는 점을 제외하고는 malloc
및 free
이 다시 반복됩니다. 정확히 GC가 제공해야하는 것은 아니지만, 예를 들어 가상 머신의 일부와 같은 장소를 가질 수 있다고 가정합니다.이 경우 루트 세트는 가상 시스템에서 사용할 수있는 정보에서 파생됩니다.
이 모든 것은 오직 보수적 인 GC에만 적용됩니다. 즉, 맹목적으로 작동하여 데이터가있는 위치에서 포인터를 검색합니다. VM에서 작업하는 경우 훨씬 쉽습니다. 포인터를 찾을 수있는 위치를 명시 적으로 나열한 VM의 모든 할당에 대해 통일 된 데이터 유형을 작성할 수 있습니다. 이와 더불어 명시적인 루트 집합을 사용하면 비 보존 GC를 만들 수 있습니다. 이것은 VM 또는 인터프리터를 구축하기에 충분해야합니다.
순수 C가 같은 스택에 액세스를 제공하지 않기 때문에 당신은, 플랫폼 독립적 인 GC 뿌리를 찾고 스택을 걸을 수 없다 완전한. –
@bdonlan : 좋은 지적, 이전 질문 중 일부를 끝내고 가장 좋은 대답을 받아 들였습니다. –
@ 스티브가 맞아야합니다. 그러나 자신의 스택 (또는 다른 GC 근원)을 대체 할 수 있다면 - 예. VM/통역사에서 - 가능해야합니다. – delnan